/*
 * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2014, 2020 Red Hat Inc. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include <stdio.h>
#include <sys/types.h>

#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "interpreter/interpreter.hpp"

#ifndef PRODUCT
const uintptr_t Assembler::asm_bp = 0x00007fffee09ac88;
#endif

#include "compiler/disassembler.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "immediate_aarch64.hpp"

extern "C" void entry(CodeBuffer *cb);

#define __ _masm.
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
#else
#define BLOCK_COMMENT(str) block_comment(str)
#endif

#define BIND(label) bind(label); __ BLOCK_COMMENT(#label ":")

static float unpack(unsigned value);

short Assembler::SIMD_Size_in_bytes[] = {
  // T8B, T16B, T4H, T8H, T2S, T4S, T1D, T2D, T1Q
       8,   16,   8,  16,   8,  16,   8,  16,  16
};

#ifdef ASSERT
static void asm_check(const unsigned int *insns, const unsigned int *insns1, size_t len) {
    bool ok = true;
    for (unsigned int i = 0; i < len; i++) {
      if (insns[i] != insns1[i]) {
        ok = false;
        printf("Ours:\n");
        Disassembler::decode((address)&insns1[i], (address)&insns1[i+1]);
        printf("Theirs:\n");
        Disassembler::decode((address)&insns[i], (address)&insns[i+1]);
        printf("\n");
      }
    }
    assert(ok, "Assembler smoke test failed");
  }

void entry(CodeBuffer *cb) {

  // {
  //   for (int i = 0; i < 256; i+=16)
  //     {
  //    printf("\"%20.20g\", ", unpack(i));
  //    printf("\"%20.20g\", ", unpack(i+1));
  //     }
  //   printf("\n");
  // }

  Assembler _masm(cb);
  address entry = __ pc();

  // Smoke test for assembler

// BEGIN  Generated code -- do not edit
// Generated by aarch64-asmtest.py
    Label back, forth;
    __ bind(back);

// ArithOp
    __ add(r15, r0, r24, Assembler::LSL, 59);          // add x15, x0, x24, LSL #59
    __ sub(r17, r22, r22, Assembler::ASR, 13);         // sub x17, x22, x22, ASR #13
    __ adds(r10, r26, r28, Assembler::LSL, 57);        // adds  x10, x26, x28, LSL #57
    __ subs(r25, r16, r24, Assembler::LSL, 18);        // subs  x25, x16, x24, LSL #18
    __ addw(r8, r5, r28, Assembler::LSL, 7);           // add w8, w5, w28, LSL #7
    __ subw(r8, r28, r1, Assembler::ASR, 28);          // sub w8, w28, w1, ASR #28
    __ addsw(r12, r2, r1, Assembler::LSL, 0);          // adds  w12, w2, w1, LSL #0
    __ subsw(r23, r5, r17, Assembler::LSR, 25);        // subs  w23, w5, w17, LSR #25
    __ andr(r21, r12, r13, Assembler::LSL, 21);        // and x21, x12, x13, LSL #21
    __ orr(r21, r15, r23, Assembler::ASR, 36);         // orr x21, x15, x23, ASR #36
    __ eor(r22, r24, r27, Assembler::ASR, 48);         // eor x22, x24, x27, ASR #48
    __ ands(r22, r15, r2, Assembler::ASR, 52);         // ands  x22, x15, x2, ASR #52
    __ andw(r1, r17, r24, Assembler::ASR, 3);          // and w1, w17, w24, ASR #3
    __ orrw(r5, r2, r6, Assembler::ASR, 11);           // orr w5, w2, w6, ASR #11
    __ eorw(r23, r1, r5, Assembler::LSR, 12);          // eor w23, w1, w5, LSR #12
    __ andsw(r0, r12, r14, Assembler::ASR, 20);        // ands  w0, w12, w14, ASR #20
    __ bic(r1, r6, r2, Assembler::LSR, 7);             // bic x1, x6, x2, LSR #7
    __ orn(r30, r8, r4, Assembler::LSL, 47);           // orn x30, x8, x4, LSL #47
    __ eon(r17, r22, r20, Assembler::ASR, 53);         // eon x17, x22, x20, ASR #53
    __ bics(r29, r15, r5, Assembler::ASR, 36);         // bics  x29, x15, x5, ASR #36
    __ bicw(r30, r23, r29, Assembler::LSR, 27);        // bic w30, w23, w29, LSR #27
    __ ornw(r12, r29, r2, Assembler::LSL, 20);         // orn w12, w29, w2, LSL #20
    __ eonw(r7, r12, r6, Assembler::ASR, 4);           // eon w7, w12, w6, ASR #4
    __ bicsw(r16, r13, r7, Assembler::ASR, 21);        // bics  w16, w13, w7, ASR #21

// AddSubImmOp
    __ addw(r5, r17, 726u);                            // add w5, w17, #726
    __ addsw(r10, r16, 347u);                          // adds  w10, w16, #347
    __ subw(r26, r5, 978u);                            // sub w26, w5, #978
    __ subsw(r21, r24, 689u);                          // subs  w21, w24, #689
    __ add(r10, r16, 987u);                            // add x10, x16, #987
    __ adds(r15, r15, 665u);                           // adds  x15, x15, #665
    __ sub(r24, r20, 39u);                             // sub x24, x20, #39
    __ subs(r10, r13, 76u);                            // subs  x10, x13, #76

// LogicalImmOp
    __ andw(r7, r19, 8388600ull);                      // and w7, w19, #0x7ffff8
    __ orrw(r5, r17, 4026535935ull);                   // orr w5, w17, #0xf0000fff
    __ eorw(r16, r28, 4186112ull);                     // eor w16, w28, #0x3fe000
    __ andsw(r14, r24, 7168ull);                       // ands  w14, w24, #0x1c00
    __ andr(r14, r27, 18446744073709543551ull);        // and x14, x27, #0xffffffffffffe07f
    __ orr(r12, r11, 576456354256912384ull);           // orr x12, x11, #0x7fffc0000000000
    __ eor(r2, r0, 18437736874454811647ull);           // eor x2, x0, #0xffe00000000003ff
    __ ands(r13, r20, 18446744073642573823ull);        // ands  x13, x20, #0xfffffffffc01ffff

// AbsOp
    __ b(__ pc());                                     // b .
    __ b(back);                                        // b back
    __ b(forth);                                       // b forth
    __ bl(__ pc());                                    // bl  .
    __ bl(back);                                       // bl  back
    __ bl(forth);                                      // bl  forth

// RegAndAbsOp
    __ cbzw(r15, __ pc());                             // cbz w15, .
    __ cbzw(r15, back);                                // cbz w15, back
    __ cbzw(r15, forth);                               // cbz w15, forth
    __ cbnzw(r28, __ pc());                            // cbnz  w28, .
    __ cbnzw(r28, back);                               // cbnz  w28, back
    __ cbnzw(r28, forth);                              // cbnz  w28, forth
    __ cbz(r27, __ pc());                              // cbz x27, .
    __ cbz(r27, back);                                 // cbz x27, back
    __ cbz(r27, forth);                                // cbz x27, forth
    __ cbnz(r0, __ pc());                              // cbnz  x0, .
    __ cbnz(r0, back);                                 // cbnz  x0, back
    __ cbnz(r0, forth);                                // cbnz  x0, forth
    __ adr(r13, __ pc());                              // adr x13, .
    __ adr(r13, back);                                 // adr x13, back
    __ adr(r13, forth);                                // adr x13, forth
    __ _adrp(r3, __ pc());                             // adrp  x3, .

// RegImmAbsOp
    __ tbz(r21, 7, __ pc());                           // tbz x21, #7, .
    __ tbz(r21, 7, back);                              // tbz x21, #7, back
    __ tbz(r21, 7, forth);                             // tbz x21, #7, forth
    __ tbnz(r15, 9, __ pc());                          // tbnz  x15, #9, .
    __ tbnz(r15, 9, back);                             // tbnz  x15, #9, back
    __ tbnz(r15, 9, forth);                            // tbnz  x15, #9, forth

// MoveWideImmOp
    __ movnw(r14, 2655, 16);                           // movn  w14, #2655, lsl 16
    __ movzw(r17, 7642, 0);                            // movz  w17, #7642, lsl 0
    __ movkw(r27, 11381, 0);                           // movk  w27, #11381, lsl 0
    __ movn(r1, 19524, 32);                            // movn  x1, #19524, lsl 32
    __ movz(r20, 21126, 16);                           // movz  x20, #21126, lsl 16
    __ movk(r20, 32462, 16);                           // movk  x20, #32462, lsl 16

// BitfieldOp
    __ sbfm(r13, r2, 28, 20);                          // sbfm  x13, x2, #28, #20
    __ bfmw(r16, r20, 19, 15);                         // bfm w16, w20, #19, #15
    __ ubfmw(r11, r11, 9, 6);                          // ubfm  w11, w11, #9, #6
    __ sbfm(r2, r4, 25, 21);                           // sbfm  x2, x4, #25, #21
    __ bfm(r13, r16, 2, 19);                           // bfm x13, x16, #2, #19
    __ ubfm(r8, r25, 8, 5);                            // ubfm  x8, x25, #8, #5

// ExtractOp
    __ extrw(r29, r27, r10, 14);                       // extr  w29, w27, w10, #14
    __ extr(r6, r20, r6, 24);                          // extr  x6, x20, x6, #24

// CondBranchOp
    __ br(Assembler::EQ, __ pc());                     // b.EQ  .
    __ br(Assembler::EQ, back);                        // b.EQ  back
    __ br(Assembler::EQ, forth);                       // b.EQ  forth
    __ br(Assembler::NE, __ pc());                     // b.NE  .
    __ br(Assembler::NE, back);                        // b.NE  back
    __ br(Assembler::NE, forth);                       // b.NE  forth
    __ br(Assembler::HS, __ pc());                     // b.HS  .
    __ br(Assembler::HS, back);                        // b.HS  back
    __ br(Assembler::HS, forth);                       // b.HS  forth
    __ br(Assembler::CS, __ pc());                     // b.CS  .
    __ br(Assembler::CS, back);                        // b.CS  back
    __ br(Assembler::CS, forth);                       // b.CS  forth
    __ br(Assembler::LO, __ pc());                     // b.LO  .
    __ br(Assembler::LO, back);                        // b.LO  back
    __ br(Assembler::LO, forth);                       // b.LO  forth
    __ br(Assembler::CC, __ pc());                     // b.CC  .
    __ br(Assembler::CC, back);                        // b.CC  back
    __ br(Assembler::CC, forth);                       // b.CC  forth
    __ br(Assembler::MI, __ pc());                     // b.MI  .
    __ br(Assembler::MI, back);                        // b.MI  back
    __ br(Assembler::MI, forth);                       // b.MI  forth
    __ br(Assembler::PL, __ pc());                     // b.PL  .
    __ br(Assembler::PL, back);                        // b.PL  back
    __ br(Assembler::PL, forth);                       // b.PL  forth
    __ br(Assembler::VS, __ pc());                     // b.VS  .
    __ br(Assembler::VS, back);                        // b.VS  back
    __ br(Assembler::VS, forth);                       // b.VS  forth
    __ br(Assembler::VC, __ pc());                     // b.VC  .
    __ br(Assembler::VC, back);                        // b.VC  back
    __ br(Assembler::VC, forth);                       // b.VC  forth
    __ br(Assembler::HI, __ pc());                     // b.HI  .
    __ br(Assembler::HI, back);                        // b.HI  back
    __ br(Assembler::HI, forth);                       // b.HI  forth
    __ br(Assembler::LS, __ pc());                     // b.LS  .
    __ br(Assembler::LS, back);                        // b.LS  back
    __ br(Assembler::LS, forth);                       // b.LS  forth
    __ br(Assembler::GE, __ pc());                     // b.GE  .
    __ br(Assembler::GE, back);                        // b.GE  back
    __ br(Assembler::GE, forth);                       // b.GE  forth
    __ br(Assembler::LT, __ pc());                     // b.LT  .
    __ br(Assembler::LT, back);                        // b.LT  back
    __ br(Assembler::LT, forth);                       // b.LT  forth
    __ br(Assembler::GT, __ pc());                     // b.GT  .
    __ br(Assembler::GT, back);                        // b.GT  back
    __ br(Assembler::GT, forth);                       // b.GT  forth
    __ br(Assembler::LE, __ pc());                     // b.LE  .
    __ br(Assembler::LE, back);                        // b.LE  back
    __ br(Assembler::LE, forth);                       // b.LE  forth
    __ br(Assembler::AL, __ pc());                     // b.AL  .
    __ br(Assembler::AL, back);                        // b.AL  back
    __ br(Assembler::AL, forth);                       // b.AL  forth
    __ br(Assembler::NV, __ pc());                     // b.NV  .
    __ br(Assembler::NV, back);                        // b.NV  back
    __ br(Assembler::NV, forth);                       // b.NV  forth

// ImmOp
    __ svc(26948);                                     // svc #26948
    __ hvc(29998);                                     // hvc #29998
    __ smc(10437);                                     // smc #10437
    __ brk(30290);                                     // brk #30290
    __ hlt(20851);                                     // hlt #20851

// Op
    __ nop();                                          // nop
    __ eret();                                         // eret
    __ drps();                                         // drps
    __ isb();                                          // isb

// SystemOp
    __ dsb(Assembler::LD);                             // dsb LD
    __ dmb(Assembler::ISH);                            // dmb ISH

// OneRegOp
    __ br(r9);                                         // br  x9
    __ blr(r9);                                        // blr x9

// LoadStoreExclusiveOp
    __ stxr(r2, r29, r11);                             // stxr  w2, x29, [x11]
    __ stlxr(r22, r5, r28);                            // stlxr w22, x5, [x28]
    __ ldxr(r14, r20);                                 // ldxr  x14, [x20]
    __ ldaxr(r29, r19);                                // ldaxr x29, [x19]
    __ stlr(r6, r21);                                  // stlr  x6, [x21]
    __ ldar(r19, r3);                                  // ldar  x19, [x3]

// LoadStoreExclusiveOp
    __ stxrw(r12, r3, r27);                            // stxr  w12, w3, [x27]
    __ stlxrw(r17, r26, r15);                          // stlxr w17, w26, [x15]
    __ ldxrw(r13, r14);                                // ldxr  w13, [x14]
    __ ldaxrw(r12, r26);                               // ldaxr w12, [x26]
    __ stlrw(r8, r17);                                 // stlr  w8, [x17]
    __ ldarw(r21, r30);                                // ldar  w21, [x30]

// LoadStoreExclusiveOp
    __ stxrh(r0, r15, r11);                            // stxrh w0, w15, [x11]
    __ stlxrh(r17, r20, r1);                           // stlxrh  w17, w20, [x1]
    __ ldxrh(r29, r8);                                 // ldxrh w29, [x8]
    __ ldaxrh(r17, r12);                               // ldaxrh  w17, [x12]
    __ stlrh(r11, r4);                                 // stlrh w11, [x4]
    __ ldarh(r16, r4);                                 // ldarh w16, [x4]

// LoadStoreExclusiveOp
    __ stxrb(r14, r5, r4);                             // stxrb w14, w5, [x4]
    __ stlxrb(r27, r17, r16);                          // stlxrb  w27, w17, [x16]
    __ ldxrb(r6, r27);                                 // ldxrb w6, [x27]
    __ ldaxrb(r27, r24);                               // ldaxrb  w27, [x24]
    __ stlrb(r10, r20);                                // stlrb w10, [x20]
    __ ldarb(r9, r26);                                 // ldarb w9, [x26]

// LoadStoreExclusiveOp
    __ ldxp(r5, r30, r28);                             // ldxp  x5, x30, [x28]
    __ ldaxp(r10, r9, r19);                            // ldaxp x10, x9, [x19]
    __ stxp(r11, r16, r21, r12);                       // stxp  w11, x16, x21, [x12]
    __ stlxp(r10, r20, r23, r4);                       // stlxp w10, x20, x23, [x4]

// LoadStoreExclusiveOp
    __ ldxpw(r22, r1, r0);                             // ldxp  w22, w1, [x0]
    __ ldaxpw(r3, r1, r8);                             // ldaxp w3, w1, [x8]
    __ stxpw(r0, r9, r23, r30);                        // stxp  w0, w9, w23, [x30]
    __ stlxpw(r23, r0, r17, r11);                      // stlxp w23, w0, w17, [x11]

// base_plus_unscaled_offset
// LoadStoreOp
    __ str(r6, Address(r10, -31));                     // str x6, [x10, -31]
    __ strw(r7, Address(r0, -5));                      // str w7, [x0, -5]
    __ strb(r5, Address(r16, -13));                    // strb  w5, [x16, -13]
    __ strh(r30, Address(r19, 31));                    // strh  w30, [x19, 31]
    __ ldr(r16, Address(r9, 119));                     // ldr x16, [x9, 119]
    __ ldrw(r8, Address(r16, 59));                     // ldr w8, [x16, 59]
    __ ldrb(r10, Address(r12, -7));                    // ldrb  w10, [x12, -7]
    __ ldrh(r14, Address(r9, -38));                    // ldrh  w14, [x9, -38]
    __ ldrsb(r24, Address(r30, -8));                   // ldrsb x24, [x30, -8]
    __ ldrsh(r7, Address(r4, 23));                     // ldrsh x7, [x4, 23]
    __ ldrshw(r17, Address(r14, -39));                 // ldrsh w17, [x14, -39]
    __ ldrsw(r11, Address(r27, -31));                  // ldrsw x11, [x27, -31]
    __ ldrd(v12, Address(r7, 65));                     // ldr d12, [x7, 65]
    __ ldrs(v0, Address(r16, -2));                     // ldr s0, [x16, -2]
    __ strd(v13, Address(r23, -161));                  // str d13, [x23, -161]
    __ strs(v21, Address(r3, -62));                    // str s21, [x3, -62]

// pre
// LoadStoreOp
    __ str(r2, Address(__ pre(r5, 100)));              // str x2, [x5, 100]!
    __ strw(r9, Address(__ pre(r1, -92)));             // str w9, [x1, -92]!
    __ strb(r27, Address(__ pre(r30, -5)));            // strb  w27, [x30, -5]!
    __ strh(r27, Address(__ pre(r15, 12)));            // strh  w27, [x15, 12]!
    __ ldr(r4, Address(__ pre(r17, -212)));            // ldr x4, [x17, -212]!
    __ ldrw(r21, Address(__ pre(r23, 30)));            // ldr w21, [x23, 30]!
    __ ldrb(r13, Address(__ pre(r17, -7)));            // ldrb  w13, [x17, -7]!
    __ ldrh(r25, Address(__ pre(r0, -50)));            // ldrh  w25, [x0, -50]!
    __ ldrsb(r1, Address(__ pre(r21, -21)));           // ldrsb x1, [x21, -21]!
    __ ldrsh(r28, Address(__ pre(r21, -54)));          // ldrsh x28, [x21, -54]!
    __ ldrshw(r11, Address(__ pre(r4, 2)));            // ldrsh w11, [x4, 2]!
    __ ldrsw(r17, Address(__ pre(r9, 61)));            // ldrsw x17, [x9, 61]!
    __ ldrd(v29, Address(__ pre(r19, 39)));            // ldr d29, [x19, 39]!
    __ ldrs(v22, Address(__ pre(r22, -85)));           // ldr s22, [x22, -85]!
    __ strd(v9, Address(__ pre(r25, -225)));           // str d9, [x25, -225]!
    __ strs(v9, Address(__ pre(r2, -15)));             // str s9, [x2, -15]!

// post
// LoadStoreOp
    __ str(r13, Address(__ post(r23, -66)));           // str x13, [x23], -66
    __ strw(r17, Address(__ post(r16, 10)));           // str w17, [x16], 10
    __ strb(r1, Address(__ post(r14, -32)));           // strb  w1, [x14], -32
    __ strh(r17, Address(__ post(r0, 6)));             // strh  w17, [x0], 6
    __ ldr(r27, Address(__ post(r25, -172)));          // ldr x27, [x25], -172
    __ ldrw(r13, Address(__ post(r25, -38)));          // ldr w13, [x25], -38
    __ ldrb(r11, Address(__ post(r25, -29)));          // ldrb  w11, [x25], -29
    __ ldrh(r30, Address(__ post(r5, 20)));            // ldrh  w30, [x5], 20
    __ ldrsb(r9, Address(__ post(r7, -7)));            // ldrsb x9, [x7], -7
    __ ldrsh(r0, Address(__ post(r3, -62)));           // ldrsh x0, [x3], -62
    __ ldrshw(r7, Address(__ post(r14, 31)));          // ldrsh w7, [x14], 31
    __ ldrsw(r17, Address(__ post(r27, 39)));          // ldrsw x17, [x27], 39
    __ ldrd(v17, Address(__ post(r4, -235)));          // ldr d17, [x4], -235
    __ ldrs(v26, Address(__ post(r21, 34)));           // ldr s26, [x21], 34
    __ strd(v5, Address(__ post(r17, -57)));           // str d5, [x17], -57
    __ strs(v13, Address(__ post(r13, -109)));         // str s13, [x13], -109

// base_plus_reg
// LoadStoreOp
    __ str(r6, Address(r16, r4, Address::sxtw(3)));    // str x6, [x16, w4, sxtw #3]
    __ strw(r9, Address(r24, r20, Address::sxtw(2)));  // str w9, [x24, w20, sxtw #2]
    __ strb(r3, Address(r29, r3, Address::lsl(0)));    // strb  w3, [x29, x3, lsl #0]
    __ strh(r10, Address(r17, r30, Address::lsl(0)));  // strh  w10, [x17, x30, lsl #0]
    __ ldr(r27, Address(r11, r7, Address::uxtw(0)));   // ldr x27, [x11, w7, uxtw #0]
    __ ldrw(r14, Address(r15, r25, Address::uxtw(0))); // ldr w14, [x15, w25, uxtw #0]
    __ ldrb(r24, Address(r14, r19, Address::lsl(0)));  // ldrb  w24, [x14, x19, lsl #0]
    __ ldrh(r16, Address(r0, r6, Address::sxtw(0)));   // ldrh  w16, [x0, w6, sxtw #0]
    __ ldrsb(r10, Address(r12, r12, Address::sxtw(0))); //  ldrsb x10, [x12, w12, sxtw #0]
    __ ldrsh(r26, Address(r12, r16, Address::uxtw(0))); //  ldrsh x26, [x12, w16, uxtw #0]
    __ ldrshw(r26, Address(r0, r14, Address::lsl(1))); // ldrsh w26, [x0, x14, lsl #1]
    __ ldrsw(r17, Address(r11, r27, Address::sxtx(2))); //  ldrsw x17, [x11, x27, sxtx #2]
    __ ldrd(v3, Address(r0, r19, Address::sxtw(3)));   // ldr d3, [x0, w19, sxtw #3]
    __ ldrs(v26, Address(r15, r9, Address::lsl(2)));   // ldr s26, [x15, x9, lsl #2]
    __ strd(v11, Address(r13, r16, Address::sxtx(0))); // str d11, [x13, x16, sxtx #0]
    __ strs(v26, Address(r19, r21, Address::uxtw(2))); // str s26, [x19, w21, uxtw #2]

// base_plus_scaled_offset
// LoadStoreOp
    __ str(r8, Address(r21, 12552));                   // str x8, [x21, 12552]
    __ strw(r10, Address(r27, 6380));                  // str w10, [x27, 6380]
    __ strb(r27, Address(r14, 1733));                  // strb  w27, [x14, 1733]
    __ strh(r16, Address(r7, 3424));                   // strh  w16, [x7, 3424]
    __ ldr(r27, Address(r9, 12520));                   // ldr x27, [x9, 12520]
    __ ldrw(r24, Address(r10, 6680));                  // ldr w24, [x10, 6680]
    __ ldrb(r24, Address(r24, 1743));                  // ldrb  w24, [x24, 1743]
    __ ldrh(r20, Address(r5, 3072));                   // ldrh  w20, [x5, 3072]
    __ ldrsb(r17, Address(r4, 1570));                  // ldrsb x17, [x4, 1570]
    __ ldrsh(r14, Address(r13, 3392));                 // ldrsh x14, [x13, 3392]
    __ ldrshw(r10, Address(r25, 3722));                // ldrsh w10, [x25, 3722]
    __ ldrsw(r2, Address(r26, 6160));                  // ldrsw x2, [x26, 6160]
    __ ldrd(v26, Address(r14, 14912));                 // ldr d26, [x14, 14912]
    __ ldrs(v28, Address(r4, 7804));                   // ldr s28, [x4, 7804]
    __ strd(v14, Address(r19, 13984));                 // str d14, [x19, 13984]
    __ strs(v23, Address(r28, 6364));                  // str s23, [x28, 6364]

// pcrel
// LoadStoreOp
    __ ldr(r8, forth);                                 // ldr x8, forth
    __ ldrw(r17, back);                                // ldr w17, back

// LoadStoreOp
    __ prfm(Address(r4, -175));                        // prfm  PLDL1KEEP, [x4, -175]

// LoadStoreOp
    __ prfm(__ pc());                                  // prfm  PLDL1KEEP, .

// LoadStoreOp
    __ prfm(Address(r8, r4, Address::sxtw(0)));        // prfm  PLDL1KEEP, [x8, w4, sxtw #0]

// LoadStoreOp
    __ prfm(Address(r12, 13248));                      // prfm  PLDL1KEEP, [x12, 13248]

// AddSubCarryOp
    __ adcw(r20, r27, r21);                            // adc w20, w27, w21
    __ adcsw(r7, r17, r6);                             // adcs  w7, w17, w6
    __ sbcw(r5, r6, r25);                              // sbc w5, w6, w25
    __ sbcsw(r30, r11, r14);                           // sbcs  w30, w11, w14
    __ adc(r3, r17, r11);                              // adc x3, x17, x11
    __ adcs(r25, r10, r17);                            // adcs  x25, x10, x17
    __ sbc(r7, r16, r23);                              // sbc x7, x16, x23
    __ sbcs(r4, r10, r5);                              // sbcs  x4, x10, x5

// AddSubExtendedOp
    __ addw(r9, r30, r9, ext::uxtx, 4);                // add w9, w30, w9, uxtx #4
    __ addsw(r0, r5, r16, ext::sxth, 2);               // adds  w0, w5, w16, sxth #2
    __ sub(r15, r29, r27, ext::sxtb, 2);               // sub x15, x29, x27, sxtb #2
    __ subsw(r11, r9, r1, ext::sxtx, 4);               // subs  w11, w9, w1, sxtx #4
    __ add(r2, r24, r6, ext::uxtw, 3);                 // add x2, x24, x6, uxtw #3
    __ adds(r19, r6, r26, ext::uxtx, 4);               // adds  x19, x6, x26, uxtx #4
    __ sub(r8, r26, r25, ext::sxtx, 3);                // sub x8, x26, x25, sxtx #3
    __ subs(r26, r20, r9, ext::uxth, 4);               // subs  x26, x20, x9, uxth #4

// ConditionalCompareOp
    __ ccmnw(r13, r26, 7u, Assembler::MI);             // ccmn  w13, w26, #7, MI
    __ ccmpw(r8, r20, 15u, Assembler::LO);             // ccmp  w8, w20, #15, LO
    __ ccmn(r22, r3, 8u, Assembler::EQ);               // ccmn  x22, x3, #8, EQ
    __ ccmp(r2, r24, 10u, Assembler::GE);              // ccmp  x2, x24, #10, GE

// ConditionalCompareImmedOp
    __ ccmnw(r8, 16, 13, Assembler::MI);               // ccmn  w8, #16, #13, MI
    __ ccmpw(r16, 12, 1, Assembler::EQ);               // ccmp  w16, #12, #1, EQ
    __ ccmn(r15, 31, 3, Assembler::VC);                // ccmn  x15, #31, #3, VC
    __ ccmp(r23, 12, 15, Assembler::EQ);               // ccmp  x23, #12, #15, EQ

// ConditionalSelectOp
    __ cselw(r14, r7, r26, Assembler::LO);             // csel  w14, w7, w26, LO
    __ csincw(r3, r27, r30, Assembler::LE);            // csinc w3, w27, w30, LE
    __ csinvw(r11, r21, r23, Assembler::EQ);           // csinv w11, w21, w23, EQ
    __ csnegw(r26, r30, r21, Assembler::GT);           // csneg w26, w30, w21, GT
    __ csel(r28, r26, r13, Assembler::HI);             // csel  x28, x26, x13, HI
    __ csinc(r17, r3, r16, Assembler::LS);             // csinc x17, x3, x16, LS
    __ csinv(r11, r5, r3, Assembler::HI);              // csinv x11, x5, x3, HI
    __ csneg(r1, r3, r19, Assembler::GT);              // csneg x1, x3, x19, GT

// TwoRegOp
    __ rbitw(r0, r9);                                  // rbit  w0, w9
    __ rev16w(r26, r14);                               // rev16 w26, w14
    __ revw(r13, r17);                                 // rev w13, w17
    __ clzw(r11, r20);                                 // clz w11, w20
    __ clsw(r28, r17);                                 // cls w28, w17
    __ rbit(r13, r4);                                  // rbit  x13, x4
    __ rev16(r1, r30);                                 // rev16 x1, x30
    __ rev32(r13, r14);                                // rev32 x13, x14
    __ rev(r5, r8);                                    // rev x5, x8
    __ clz(r2, r25);                                   // clz x2, x25
    __ cls(r20, r8);                                   // cls x20, x8

// ThreeRegOp
    __ udivw(r21, r25, r27);                           // udiv  w21, w25, w27
    __ sdivw(r13, r10, r16);                           // sdiv  w13, w10, w16
    __ lslvw(r28, r1, r17);                            // lslv  w28, w1, w17
    __ lsrvw(r25, r23, r10);                           // lsrv  w25, w23, w10
    __ asrvw(r7, r3, r7);                              // asrv  w7, w3, w7
    __ rorvw(r14, r30, r14);                           // rorv  w14, w30, w14
    __ udiv(r12, r22, r15);                            // udiv  x12, x22, x15
    __ sdiv(r2, r25, r13);                             // sdiv  x2, x25, x13
    __ lslv(r7, r23, r21);                             // lslv  x7, x23, x21
    __ lsrv(r11, r12, r0);                             // lsrv  x11, x12, x0
    __ asrv(r30, r9, r28);                             // asrv  x30, x9, x28
    __ rorv(r13, r5, r22);                             // rorv  x13, x5, x22
    __ umulh(r5, r21, r4);                             // umulh x5, x21, x4
    __ smulh(r17, r2, r7);                             // smulh x17, x2, x7

// FourRegMulOp
    __ maddw(r12, r12, r17, r12);                      // madd  w12, w12, w17, w12
    __ msubw(r30, r15, r1, r27);                       // msub  w30, w15, w1, w27
    __ madd(r2, r19, r17, r29);                        // madd  x2, x19, x17, x29
    __ msub(r4, r23, r3, r30);                         // msub  x4, x23, x3, x30
    __ smaddl(r15, r23, r17, r15);                     // smaddl  x15, w23, w17, x15
    __ smsubl(r27, r12, r1, r13);                      // smsubl  x27, w12, w1, x13
    __ umaddl(r6, r13, r12, r17);                      // umaddl  x6, w13, w12, x17
    __ umsubl(r25, r1, r6, r10);                       // umsubl  x25, w1, w6, x10

// ThreeRegFloatOp
    __ fmuls(v17, v3, v4);                             // fmul  s17, s3, s4
    __ fdivs(v16, v5, v21);                            // fdiv  s16, s5, s21
    __ fadds(v3, v27, v17);                            // fadd  s3, s27, s17
    __ fsubs(v25, v10, v15);                           // fsub  s25, s10, s15
    __ fmuls(v10, v17, v0);                            // fmul  s10, s17, s0
    __ fmuld(v28, v26, v3);                            // fmul  d28, d26, d3
    __ fdivd(v4, v0, v27);                             // fdiv  d4, d0, d27
    __ faddd(v28, v14, v2);                            // fadd  d28, d14, d2
    __ fsubd(v12, v26, v23);                           // fsub  d12, d26, d23
    __ fmuld(v15, v30, v1);                            // fmul  d15, d30, d1

// FourRegFloatOp
    __ fmadds(v4, v5, v5, v13);                        // fmadd s4, s5, s5, s13
    __ fmsubs(v21, v13, v28, v1);                      // fmsub s21, s13, s28, s1
    __ fnmadds(v17, v3, v29, v7);                      // fnmadd  s17, s3, s29, s7
    __ fnmadds(v23, v25, v29, v26);                    // fnmadd  s23, s25, s29, s26
    __ fmaddd(v14, v7, v30, v26);                      // fmadd d14, d7, d30, d26
    __ fmsubd(v22, v7, v10, v9);                       // fmsub d22, d7, d10, d9
    __ fnmaddd(v7, v7, v14, v9);                       // fnmadd  d7, d7, d14, d9
    __ fnmaddd(v14, v24, v15, v24);                    // fnmadd  d14, d24, d15, d24

// TwoRegFloatOp
    __ fmovs(v22, v2);                                 // fmov  s22, s2
    __ fabss(v0, v3);                                  // fabs  s0, s3
    __ fnegs(v9, v17);                                 // fneg  s9, s17
    __ fsqrts(v24, v11);                               // fsqrt s24, s11
    __ fcvts(v15, v25);                                // fcvt  d15, s25
    __ fmovd(v4, v3);                                  // fmov  d4, d3
    __ fabsd(v26, v22);                                // fabs  d26, d22
    __ fnegd(v30, v19);                                // fneg  d30, d19
    __ fsqrtd(v12, v14);                               // fsqrt d12, d14
    __ fcvtd(v17, v7);                                 // fcvt  s17, d7

// FloatConvertOp
    __ fcvtzsw(r24, v14);                              // fcvtzs  w24, s14
    __ fcvtzs(r13, v26);                               // fcvtzs  x13, s26
    __ fcvtzdw(r2, v1);                                // fcvtzs  w2, d1
    __ fcvtzd(r5, v11);                                // fcvtzs  x5, d11
    __ scvtfws(v14, r19);                              // scvtf s14, w19
    __ scvtfs(v1, r22);                                // scvtf s1, x22
    __ scvtfwd(v27, r17);                              // scvtf d27, w17
    __ scvtfd(v22, r9);                                // scvtf d22, x9
    __ fmovs(r14, v3);                                 // fmov  w14, s3
    __ fmovd(r12, v17);                                // fmov  x12, d17
    __ fmovs(v8, r27);                                 // fmov  s8, w27
    __ fmovd(v29, r28);                                // fmov  d29, x28

// TwoRegFloatOp
    __ fcmps(v0, v30);                                 // fcmp  s0, s30
    __ fcmpd(v12, v9);                                 // fcmp  d12, d9
    __ fcmps(v10, 0.0);                                // fcmp  s10, #0.0
    __ fcmpd(v25, 0.0);                                // fcmp  d25, #0.0

// LoadStorePairOp
    __ stpw(r8, r30, Address(r27, -144));              // stp w8, w30, [x27, #-144]
    __ ldpw(r21, r19, Address(r24, 80));               // ldp w21, w19, [x24, #80]
    __ ldpsw(r16, r27, Address(r2, -240));             // ldpsw x16, x27, [x2, #-240]
    __ stp(r21, r5, Address(r6, -128));                // stp x21, x5, [x6, #-128]
    __ ldp(r29, r25, Address(r28, -32));               // ldp x29, x25, [x28, #-32]

// LoadStorePairOp
    __ stpw(r8, r13, Address(__ pre(r0, 128)));        // stp w8, w13, [x0, #128]!
    __ ldpw(r25, r20, Address(__ pre(r1, -160)));      // ldp w25, w20, [x1, #-160]!
    __ ldpsw(r14, r24, Address(__ pre(r22, -32)));     // ldpsw x14, x24, [x22, #-32]!
    __ stp(r17, r1, Address(__ pre(r6, 80)));          // stp x17, x1, [x6, #80]!
    __ ldp(r21, r17, Address(__ pre(r25, -64)));       // ldp x21, x17, [x25, #-64]!

// LoadStorePairOp
    __ stpw(r17, r21, Address(__ post(r20, -128)));    // stp w17, w21, [x20], #-128
    __ ldpw(r28, r28, Address(__ post(r2, 64)));       // ldp w28, w28, [x2], #64
    __ ldpsw(r19, r30, Address(__ post(r10, -256)));   // ldpsw x19, x30, [x10], #-256
    __ stp(r17, r15, Address(__ post(r17, -16)));      // stp x17, x15, [x17], #-16
    __ ldp(r17, r0, Address(__ post(r25, -32)));       // ldp x17, x0, [x25], #-32

// LoadStorePairOp
    __ stnpw(r14, r5, Address(r24, -32));              // stnp  w14, w5, [x24, #-32]
    __ ldnpw(r23, r19, Address(r1, 112));              // ldnp  w23, w19, [x1, #112]
    __ stnp(r11, r6, Address(r14, 64));                // stnp  x11, x6, [x14, #64]
    __ ldnp(r2, r11, Address(r27, -224));              // ldnp  x2, x11, [x27, #-224]

// LdStSIMDOp
    __ ld1(v16, __ T8B, Address(r17));                 // ld1 {v16.8B}, [x17]
    __ ld1(v29, v30, __ T16B, Address(__ post(r9, 32))); // ld1 {v29.16B, v30.16B}, [x9], 32
    __ ld1(v30, v31, v0, __ T1D, Address(__ post(r24, r21))); //  ld1 {v30.1D, v31.1D, v0.1D}, [x24], x21
    __ ld1(v0, v1, v2, v3, __ T8H, Address(__ post(r2, 64))); //  ld1 {v0.8H, v1.8H, v2.8H, v3.8H}, [x2], 64
    __ ld1r(v20, __ T8B, Address(r9));                 // ld1r  {v20.8B}, [x9]
    __ ld1r(v17, __ T4S, Address(__ post(r0, 4)));     // ld1r  {v17.4S}, [x0], 4
    __ ld1r(v21, __ T1D, Address(__ post(r22, r26)));  // ld1r  {v21.1D}, [x22], x26
    __ ld2(v19, v20, __ T2D, Address(r25));            // ld2 {v19.2D, v20.2D}, [x25]
    __ ld2(v10, v11, __ T4H, Address(__ post(r5, 16))); //  ld2 {v10.4H, v11.4H}, [x5], 16
    __ ld2r(v10, v11, __ T16B, Address(r24));          // ld2r  {v10.16B, v11.16B}, [x24]
    __ ld2r(v13, v14, __ T2S, Address(__ post(r29, 8))); // ld2r  {v13.2S, v14.2S}, [x29], 8
    __ ld2r(v22, v23, __ T2D, Address(__ post(r28, r2))); //  ld2r  {v22.2D, v23.2D}, [x28], x2
    __ ld3(v30, v31, v0, __ T4S, Address(__ post(r4, r11))); // ld3 {v30.4S, v31.4S, v0.4S}, [x4], x11
    __ ld3(v29, v30, v31, __ T2S, Address(r0));        // ld3 {v29.2S, v30.2S, v31.2S}, [x0]
    __ ld3r(v23, v24, v25, __ T8H, Address(r27));      // ld3r  {v23.8H, v24.8H, v25.8H}, [x27]
    __ ld3r(v3, v4, v5, __ T4S, Address(__ post(r10, 12))); //  ld3r  {v3.4S, v4.4S, v5.4S}, [x10], 12
    __ ld3r(v19, v20, v21, __ T1D, Address(__ post(r14, r22))); //  ld3r  {v19.1D, v20.1D, v21.1D}, [x14], x22
    __ ld4(v14, v15, v16, v17, __ T8H, Address(__ post(r0, 64))); //  ld4 {v14.8H, v15.8H, v16.8H, v17.8H}, [x0], 64
    __ ld4(v30, v31, v0, v1, __ T8B, Address(__ post(r22, r25))); //  ld4 {v30.8B, v31.8B, v0.8B, v1.8B}, [x22], x25
    __ ld4r(v25, v26, v27, v28, __ T8B, Address(r0));  // ld4r  {v25.8B, v26.8B, v27.8B, v28.8B}, [x0]
    __ ld4r(v10, v11, v12, v13, __ T4H, Address(__ post(r8, 8))); //  ld4r  {v10.4H, v11.4H, v12.4H, v13.4H}, [x8], 8
    __ ld4r(v1, v2, v3, v4, __ T2S, Address(__ post(r6, r28))); //  ld4r  {v1.2S, v2.2S, v3.2S, v4.2S}, [x6], x28

// SpecialCases
    __ ccmn(zr, zr, 3u, Assembler::LE);                // ccmn  xzr, xzr, #3, LE
    __ ccmnw(zr, zr, 5u, Assembler::EQ);               // ccmn  wzr, wzr, #5, EQ
    __ ccmp(zr, 1, 4u, Assembler::NE);                 // ccmp  xzr, 1, #4, NE
    __ ccmpw(zr, 2, 2, Assembler::GT);                 // ccmp  wzr, 2, #2, GT
    __ extr(zr, zr, zr, 0);                            // extr  xzr, xzr, xzr, 0
    __ stlxp(r0, zr, zr, sp);                          // stlxp w0, xzr, xzr, [sp]
    __ stlxpw(r2, zr, zr, r3);                         // stlxp w2, wzr, wzr, [x3]
    __ stxp(r4, zr, zr, r5);                           // stxp  w4, xzr, xzr, [x5]
    __ stxpw(r6, zr, zr, sp);                          // stxp  w6, wzr, wzr, [sp]
    __ dup(v0, __ T16B, zr);                           // dup v0.16b, wzr
    __ mov(v1, __ T1D, 0, zr);                         // mov v1.d[0], xzr
    __ mov(v1, __ T2S, 1, zr);                         // mov v1.s[1], wzr
    __ mov(v1, __ T4H, 2, zr);                         // mov v1.h[2], wzr
    __ mov(v1, __ T8B, 3, zr);                         // mov v1.b[3], wzr
    __ ld1(v31, v0, __ T2D, Address(__ post(r1, r0))); // ld1 {v31.2d, v0.2d}, [x1], x0

// FloatImmediateOp
    __ fmovd(v0, 2.0);                                 // fmov d0, #2.0
    __ fmovd(v0, 2.125);                               // fmov d0, #2.125
    __ fmovd(v0, 4.0);                                 // fmov d0, #4.0
    __ fmovd(v0, 4.25);                                // fmov d0, #4.25
    __ fmovd(v0, 8.0);                                 // fmov d0, #8.0
    __ fmovd(v0, 8.5);                                 // fmov d0, #8.5
    __ fmovd(v0, 16.0);                                // fmov d0, #16.0
    __ fmovd(v0, 17.0);                                // fmov d0, #17.0
    __ fmovd(v0, 0.125);                               // fmov d0, #0.125
    __ fmovd(v0, 0.1328125);                           // fmov d0, #0.1328125
    __ fmovd(v0, 0.25);                                // fmov d0, #0.25
    __ fmovd(v0, 0.265625);                            // fmov d0, #0.265625
    __ fmovd(v0, 0.5);                                 // fmov d0, #0.5
    __ fmovd(v0, 0.53125);                             // fmov d0, #0.53125
    __ fmovd(v0, 1.0);                                 // fmov d0, #1.0
    __ fmovd(v0, 1.0625);                              // fmov d0, #1.0625
    __ fmovd(v0, -2.0);                                // fmov d0, #-2.0
    __ fmovd(v0, -2.125);                              // fmov d0, #-2.125
    __ fmovd(v0, -4.0);                                // fmov d0, #-4.0
    __ fmovd(v0, -4.25);                               // fmov d0, #-4.25
    __ fmovd(v0, -8.0);                                // fmov d0, #-8.0
    __ fmovd(v0, -8.5);                                // fmov d0, #-8.5
    __ fmovd(v0, -16.0);                               // fmov d0, #-16.0
    __ fmovd(v0, -17.0);                               // fmov d0, #-17.0
    __ fmovd(v0, -0.125);                              // fmov d0, #-0.125
    __ fmovd(v0, -0.1328125);                          // fmov d0, #-0.1328125
    __ fmovd(v0, -0.25);                               // fmov d0, #-0.25
    __ fmovd(v0, -0.265625);                           // fmov d0, #-0.265625
    __ fmovd(v0, -0.5);                                // fmov d0, #-0.5
    __ fmovd(v0, -0.53125);                            // fmov d0, #-0.53125
    __ fmovd(v0, -1.0);                                // fmov d0, #-1.0
    __ fmovd(v0, -1.0625);                             // fmov d0, #-1.0625

// LSEOp
    __ swp(Assembler::xword, r16, r20, r15);           // swp x16, x20, [x15]
    __ ldadd(Assembler::xword, r2, r7, r28);           // ldadd x2, x7, [x28]
    __ ldbic(Assembler::xword, r20, r10, r25);         // ldclr x20, x10, [x25]
    __ ldeor(Assembler::xword, r22, r11, r2);          // ldeor x22, x11, [x2]
    __ ldorr(Assembler::xword, r1, r10, r19);          // ldset x1, x10, [x19]
    __ ldsmin(Assembler::xword, r14, r21, r3);         // ldsmin  x14, x21, [x3]
    __ ldsmax(Assembler::xword, r28, r27, r13);        // ldsmax  x28, x27, [x13]
    __ ldumin(Assembler::xword, r17, r30, r21);        // ldumin  x17, x30, [x21]
    __ ldumax(Assembler::xword, r27, r16, r29);        // ldumax  x27, x16, [x29]

// LSEOp
    __ swpa(Assembler::xword, r30, r9, r0);            // swpa  x30, x9, [x0]
    __ ldadda(Assembler::xword, r28, r27, r28);        // ldadda  x28, x27, [x28]
    __ ldbica(Assembler::xword, r21, r25, r10);        // ldclra  x21, x25, [x10]
    __ ldeora(Assembler::xword, zr, r20, r15);         // ldeora  xzr, x20, [x15]
    __ ldorra(Assembler::xword, r1, r25, r14);         // ldseta  x1, x25, [x14]
    __ ldsmina(Assembler::xword, r21, r26, r29);       // ldsmina x21, x26, [x29]
    __ ldsmaxa(Assembler::xword, r8, r29, r25);        // ldsmaxa x8, x29, [x25]
    __ ldumina(Assembler::xword, r13, r2, r25);        // ldumina x13, x2, [x25]
    __ ldumaxa(Assembler::xword, r15, r23, r0);        // ldumaxa x15, x23, [x0]

// LSEOp
    __ swpal(Assembler::xword, r3, r1, r2);            // swpal x3, x1, [x2]
    __ ldaddal(Assembler::xword, r28, r3, r20);        // ldaddal x28, x3, [x20]
    __ ldbical(Assembler::xword, r14, zr, r14);        // ldclral x14, xzr, [x14]
    __ ldeoral(Assembler::xword, r7, r28, r2);         // ldeoral x7, x28, [x2]
    __ ldorral(Assembler::xword, r0, r11, r5);         // ldsetal x0, x11, [x5]
    __ ldsminal(Assembler::xword, r11, r14, r20);      // ldsminal  x11, x14, [x20]
    __ ldsmaxal(Assembler::xword, zr, r4, r2);         // ldsmaxal  xzr, x4, [x2]
    __ lduminal(Assembler::xword, r26, r0, r22);       // lduminal  x26, x0, [x22]
    __ ldumaxal(Assembler::xword, r17, r1, r13);       // ldumaxal  x17, x1, [x13]

// LSEOp
    __ swpl(Assembler::xword, r23, r26, r20);          // swpl  x23, x26, [x20]
    __ ldaddl(Assembler::xword, r14, r11, r12);        // ldaddl  x14, x11, [x12]
    __ ldbicl(Assembler::xword, r12, zr, r15);         // ldclrl  x12, xzr, [x15]
    __ ldeorl(Assembler::xword, r27, r14, r8);         // ldeorl  x27, x14, [x8]
    __ ldorrl(Assembler::xword, r10, r30, r25);        // ldsetl  x10, x30, [x25]
    __ ldsminl(Assembler::xword, r22, r7, r16);        // ldsminl x22, x7, [x16]
    __ ldsmaxl(Assembler::xword, r1, r16, r8);         // ldsmaxl x1, x16, [x8]
    __ lduminl(Assembler::xword, r1, r1, r26);         // lduminl x1, x1, [x26]
    __ ldumaxl(Assembler::xword, r0, r23, r15);        // ldumaxl x0, x23, [x15]

// LSEOp
    __ swp(Assembler::word, r11, r16, r8);             // swp w11, w16, [x8]
    __ ldadd(Assembler::word, r1, r7, r14);            // ldadd w1, w7, [x14]
    __ ldbic(Assembler::word, r16, zr, r9);            // ldclr w16, wzr, [x9]
    __ ldeor(Assembler::word, r22, r6, r13);           // ldeor w22, w6, [x13]
    __ ldorr(Assembler::word, r11, r13, r4);           // ldset w11, w13, [x4]
    __ ldsmin(Assembler::word, r16, r22, r0);          // ldsmin  w16, w22, [x0]
    __ ldsmax(Assembler::word, r28, zr, r10);          // ldsmax  w28, wzr, [x10]
    __ ldumin(Assembler::word, r16, r5, r8);           // ldumin  w16, w5, [x8]
    __ ldumax(Assembler::word, r26, r20, r15);         // ldumax  w26, w20, [x15]

// LSEOp
    __ swpa(Assembler::word, r27, r6, r16);            // swpa  w27, w6, [x16]
    __ ldadda(Assembler::word, zr, zr, r2);            // ldadda  wzr, wzr, [x2]
    __ ldbica(Assembler::word, r24, r28, r8);          // ldclra  w24, w28, [x8]
    __ ldeora(Assembler::word, r15, r9, r23);          // ldeora  w15, w9, [x23]
    __ ldorra(Assembler::word, r26, r2, r7);           // ldseta  w26, w2, [x7]
    __ ldsmina(Assembler::word, r3, r17, r15);         // ldsmina w3, w17, [x15]
    __ ldsmaxa(Assembler::word, r19, r5, r21);         // ldsmaxa w19, w5, [x21]
    __ ldumina(Assembler::word, r7, r26, r12);         // ldumina w7, w26, [x12]
    __ ldumaxa(Assembler::word, r12, r7, r29);         // ldumaxa w12, w7, [x29]

// LSEOp
    __ swpal(Assembler::word, r9, r8, r20);            // swpal w9, w8, [x20]
    __ ldaddal(Assembler::word, r8, zr, r30);          // ldaddal w8, wzr, [x30]
    __ ldbical(Assembler::word, r0, r6, r12);          // ldclral w0, w6, [x12]
    __ ldeoral(Assembler::word, r17, r23, r2);         // ldeoral w17, w23, [x2]
    __ ldorral(Assembler::word, r0, r30, r1);          // ldsetal w0, w30, [x1]
    __ ldsminal(Assembler::word, r22, r3, r15);        // ldsminal  w22, w3, [x15]
    __ ldsmaxal(Assembler::word, r25, r21, r13);       // ldsmaxal  w25, w21, [x13]
    __ lduminal(Assembler::word, r13, r24, r27);       // lduminal  w13, w24, [x27]
    __ ldumaxal(Assembler::word, r20, r3, r11);        // ldumaxal  w20, w3, [x11]

// LSEOp
    __ swpl(Assembler::word, r3, r13, r21);            // swpl  w3, w13, [x21]
    __ ldaddl(Assembler::word, r26, r15, r26);         // ldaddl  w26, w15, [x26]
    __ ldbicl(Assembler::word, r9, r19, r2);           // ldclrl  w9, w19, [x2]
    __ ldeorl(Assembler::word, r24, r29, r7);          // ldeorl  w24, w29, [x7]
    __ ldorrl(Assembler::word, r29, r25, r15);         // ldsetl  w29, w25, [x15]
    __ ldsminl(Assembler::word, r11, r30, r7);         // ldsminl w11, w30, [x7]
    __ ldsmaxl(Assembler::word, r11, r2, r6);          // ldsmaxl w11, w2, [x6]
    __ lduminl(Assembler::word, r16, r11, r14);        // lduminl w16, w11, [x14]
    __ ldumaxl(Assembler::word, r5, r8, r11);          // ldumaxl w5, w8, [x11]

    __ bind(forth);

/*
aarch64ops.o:     file format elf64-littleaarch64


Disassembly of section .text:

0000000000000000 <back>:
   0: 8b18ec0f  add x15, x0, x24, lsl #59
   4: cb9636d1  sub x17, x22, x22, asr #13
   8: ab1ce74a  adds  x10, x26, x28, lsl #57
   c: eb184a19  subs  x25, x16, x24, lsl #18
  10: 0b1c1ca8  add w8, w5, w28, lsl #7
  14: 4b817388  sub w8, w28, w1, asr #28
  18: 2b01004c  adds  w12, w2, w1
  1c: 6b5164b7  subs  w23, w5, w17, lsr #25
  20: 8a0d5595  and x21, x12, x13, lsl #21
  24: aa9791f5  orr x21, x15, x23, asr #36
  28: ca9bc316  eor x22, x24, x27, asr #48
  2c: ea82d1f6  ands  x22, x15, x2, asr #52
  30: 0a980e21  and w1, w17, w24, asr #3
  34: 2a862c45  orr w5, w2, w6, asr #11
  38: 4a453037  eor w23, w1, w5, lsr #12
  3c: 6a8e5180  ands  w0, w12, w14, asr #20
  40: 8a621cc1  bic x1, x6, x2, lsr #7
  44: aa24bd1e  orn x30, x8, x4, lsl #47
  48: cab4d6d1  eon x17, x22, x20, asr #53
  4c: eaa591fd  bics  x29, x15, x5, asr #36
  50: 0a7d6efe  bic w30, w23, w29, lsr #27
  54: 2a2253ac  orn w12, w29, w2, lsl #20
  58: 4aa61187  eon w7, w12, w6, asr #4
  5c: 6aa755b0  bics  w16, w13, w7, asr #21
  60: 110b5a25  add w5, w17, #0x2d6
  64: 31056e0a  adds  w10, w16, #0x15b
  68: 510f48ba  sub w26, w5, #0x3d2
  6c: 710ac715  subs  w21, w24, #0x2b1
  70: 910f6e0a  add x10, x16, #0x3db
  74: b10a65ef  adds  x15, x15, #0x299
  78: d1009e98  sub x24, x20, #0x27
  7c: f10131aa  subs  x10, x13, #0x4c
  80: 121d4e67  and w7, w19, #0x7ffff8
  84: 32043e25  orr w5, w17, #0xf0000fff
  88: 52132390  eor w16, w28, #0x3fe000
  8c: 72160b0e  ands  w14, w24, #0x1c00
  90: 9273e76e  and x14, x27, #0xffffffffffffe07f
  94: b256416c  orr x12, x11, #0x7fffc0000000000
  98: d24b5002  eor x2, x0, #0xffe00000000003ff
  9c: f266da8d  ands  x13, x20, #0xfffffffffc01ffff
  a0: 14000000  b a0 <back+0xa0>
  a4: 17ffffd7  b 0 <back>
  a8: 140001ee  b 860 <forth>
  ac: 94000000  bl  ac <back+0xac>
  b0: 97ffffd4  bl  0 <back>
  b4: 940001eb  bl  860 <forth>
  b8: 3400000f  cbz w15, b8 <back+0xb8>
  bc: 34fffa2f  cbz w15, 0 <back>
  c0: 34003d0f  cbz w15, 860 <forth>
  c4: 3500001c  cbnz  w28, c4 <back+0xc4>
  c8: 35fff9dc  cbnz  w28, 0 <back>
  cc: 35003cbc  cbnz  w28, 860 <forth>
  d0: b400001b  cbz x27, d0 <back+0xd0>
  d4: b4fff97b  cbz x27, 0 <back>
  d8: b4003c5b  cbz x27, 860 <forth>
  dc: b5000000  cbnz  x0, dc <back+0xdc>
  e0: b5fff900  cbnz  x0, 0 <back>
  e4: b5003be0  cbnz  x0, 860 <forth>
  e8: 1000000d  adr x13, e8 <back+0xe8>
  ec: 10fff8ad  adr x13, 0 <back>
  f0: 10003b8d  adr x13, 860 <forth>
  f4: 90000003  adrp  x3, 0 <back>
  f8: 36380015  tbz w21, #7, f8 <back+0xf8>
  fc: 363ff835  tbz w21, #7, 0 <back>
 100: 36383b15  tbz w21, #7, 860 <forth>
 104: 3748000f  tbnz  w15, #9, 104 <back+0x104>
 108: 374ff7cf  tbnz  w15, #9, 0 <back>
 10c: 37483aaf  tbnz  w15, #9, 860 <forth>
 110: 12a14bee  mov w14, #0xf5a0ffff              // #-173998081
 114: 5283bb51  mov w17, #0x1dda                  // #7642
 118: 72858ebb  movk  w27, #0x2c75
 11c: 92c98881  mov x1, #0xffffb3bbffffffff     // #-83854941487105
 120: d2aa50d4  mov x20, #0x52860000              // #1384513536
 124: f2afd9d4  movk  x20, #0x7ece, lsl #16
 128: 935c504d  sbfiz x13, x2, #36, #21
 12c: 33133e90  bfi w16, w20, #13, #16
 130: 5309196b  ubfiz w11, w11, #23, #7
 134: 93595482  sbfiz x2, x4, #39, #22
 138: b3424e0d  bfxil x13, x16, #2, #18
 13c: d3481728  ubfiz x8, x25, #56, #6
 140: 138a3b7d  extr  w29, w27, w10, #14
 144: 93c66286  extr  x6, x20, x6, #24
 148: 54000000  b.eq  148 <back+0x148>  // b.none
 14c: 54fff5a0  b.eq  0 <back>  // b.none
 150: 54003880  b.eq  860 <forth>  // b.none
 154: 54000001  b.ne  154 <back+0x154>  // b.any
 158: 54fff541  b.ne  0 <back>  // b.any
 15c: 54003821  b.ne  860 <forth>  // b.any
 160: 54000002  b.cs  160 <back+0x160>  // b.hs, b.nlast
 164: 54fff4e2  b.cs  0 <back>  // b.hs, b.nlast
 168: 540037c2  b.cs  860 <forth>  // b.hs, b.nlast
 16c: 54000002  b.cs  16c <back+0x16c>  // b.hs, b.nlast
 170: 54fff482  b.cs  0 <back>  // b.hs, b.nlast
 174: 54003762  b.cs  860 <forth>  // b.hs, b.nlast
 178: 54000003  b.cc  178 <back+0x178>  // b.lo, b.ul, b.last
 17c: 54fff423  b.cc  0 <back>  // b.lo, b.ul, b.last
 180: 54003703  b.cc  860 <forth>  // b.lo, b.ul, b.last
 184: 54000003  b.cc  184 <back+0x184>  // b.lo, b.ul, b.last
 188: 54fff3c3  b.cc  0 <back>  // b.lo, b.ul, b.last
 18c: 540036a3  b.cc  860 <forth>  // b.lo, b.ul, b.last
 190: 54000004  b.mi  190 <back+0x190>  // b.first
 194: 54fff364  b.mi  0 <back>  // b.first
 198: 54003644  b.mi  860 <forth>  // b.first
 19c: 54000005  b.pl  19c <back+0x19c>  // b.nfrst
 1a0: 54fff305  b.pl  0 <back>  // b.nfrst
 1a4: 540035e5  b.pl  860 <forth>  // b.nfrst
 1a8: 54000006  b.vs  1a8 <back+0x1a8>
 1ac: 54fff2a6  b.vs  0 <back>
 1b0: 54003586  b.vs  860 <forth>
 1b4: 54000007  b.vc  1b4 <back+0x1b4>
 1b8: 54fff247  b.vc  0 <back>
 1bc: 54003527  b.vc  860 <forth>
 1c0: 54000008  b.hi  1c0 <back+0x1c0>  // b.pmore
 1c4: 54fff1e8  b.hi  0 <back>  // b.pmore
 1c8: 540034c8  b.hi  860 <forth>  // b.pmore
 1cc: 54000009  b.ls  1cc <back+0x1cc>  // b.plast
 1d0: 54fff189  b.ls  0 <back>  // b.plast
 1d4: 54003469  b.ls  860 <forth>  // b.plast
 1d8: 5400000a  b.ge  1d8 <back+0x1d8>  // b.tcont
 1dc: 54fff12a  b.ge  0 <back>  // b.tcont
 1e0: 5400340a  b.ge  860 <forth>  // b.tcont
 1e4: 5400000b  b.lt  1e4 <back+0x1e4>  // b.tstop
 1e8: 54fff0cb  b.lt  0 <back>  // b.tstop
 1ec: 540033ab  b.lt  860 <forth>  // b.tstop
 1f0: 5400000c  b.gt  1f0 <back+0x1f0>
 1f4: 54fff06c  b.gt  0 <back>
 1f8: 5400334c  b.gt  860 <forth>
 1fc: 5400000d  b.le  1fc <back+0x1fc>
 200: 54fff00d  b.le  0 <back>
 204: 540032ed  b.le  860 <forth>
 208: 5400000e  b.al  208 <back+0x208>
 20c: 54ffefae  b.al  0 <back>
 210: 5400328e  b.al  860 <forth>
 214: 5400000f  b.nv  214 <back+0x214>
 218: 54ffef4f  b.nv  0 <back>
 21c: 5400322f  b.nv  860 <forth>
 220: d40d2881  svc #0x6944
 224: d40ea5c2  hvc #0x752e
 228: d40518a3  smc #0x28c5
 22c: d42eca40  brk #0x7652
 230: d44a2e60  hlt #0x5173
 234: d503201f  nop
 238: d69f03e0  eret
 23c: d6bf03e0  drps
 240: d5033fdf  isb
 244: d5033d9f  dsb ld
 248: d5033bbf  dmb ish
 24c: d61f0120  br  x9
 250: d63f0120  blr x9
 254: c8027d7d  stxr  w2, x29, [x11]
 258: c816ff85  stlxr w22, x5, [x28]
 25c: c85f7e8e  ldxr  x14, [x20]
 260: c85ffe7d  ldaxr x29, [x19]
 264: c89ffea6  stlr  x6, [x21]
 268: c8dffc73  ldar  x19, [x3]
 26c: 880c7f63  stxr  w12, w3, [x27]
 270: 8811fdfa  stlxr w17, w26, [x15]
 274: 885f7dcd  ldxr  w13, [x14]
 278: 885fff4c  ldaxr w12, [x26]
 27c: 889ffe28  stlr  w8, [x17]
 280: 88dfffd5  ldar  w21, [x30]
 284: 48007d6f  stxrh w0, w15, [x11]
 288: 4811fc34  stlxrh  w17, w20, [x1]
 28c: 485f7d1d  ldxrh w29, [x8]
 290: 485ffd91  ldaxrh  w17, [x12]
 294: 489ffc8b  stlrh w11, [x4]
 298: 48dffc90  ldarh w16, [x4]
 29c: 080e7c85  stxrb w14, w5, [x4]
 2a0: 081bfe11  stlxrb  w27, w17, [x16]
 2a4: 085f7f66  ldxrb w6, [x27]
 2a8: 085fff1b  ldaxrb  w27, [x24]
 2ac: 089ffe8a  stlrb w10, [x20]
 2b0: 08dfff49  ldarb w9, [x26]
 2b4: c87f7b85  ldxp  x5, x30, [x28]
 2b8: c87fa66a  ldaxp x10, x9, [x19]
 2bc: c82b5590  stxp  w11, x16, x21, [x12]
 2c0: c82adc94  stlxp w10, x20, x23, [x4]
 2c4: 887f0416  ldxp  w22, w1, [x0]
 2c8: 887f8503  ldaxp w3, w1, [x8]
 2cc: 88205fc9  stxp  w0, w9, w23, [x30]
 2d0: 8837c560  stlxp w23, w0, w17, [x11]
 2d4: f81e1146  stur  x6, [x10, #-31]
 2d8: b81fb007  stur  w7, [x0, #-5]
 2dc: 381f3205  sturb w5, [x16, #-13]
 2e0: 7801f27e  sturh w30, [x19, #31]
 2e4: f8477130  ldur  x16, [x9, #119]
 2e8: b843b208  ldur  w8, [x16, #59]
 2ec: 385f918a  ldurb w10, [x12, #-7]
 2f0: 785da12e  ldurh w14, [x9, #-38]
 2f4: 389f83d8  ldursb  x24, [x30, #-8]
 2f8: 78817087  ldursh  x7, [x4, #23]
 2fc: 78dd91d1  ldursh  w17, [x14, #-39]
 300: b89e136b  ldursw  x11, [x27, #-31]
 304: fc4410ec  ldur  d12, [x7, #65]
 308: bc5fe200  ldur  s0, [x16, #-2]
 30c: fc15f2ed  stur  d13, [x23, #-161]
 310: bc1c2075  stur  s21, [x3, #-62]
 314: f8064ca2  str x2, [x5, #100]!
 318: b81a4c29  str w9, [x1, #-92]!
 31c: 381fbfdb  strb  w27, [x30, #-5]!
 320: 7800cdfb  strh  w27, [x15, #12]!
 324: f852ce24  ldr x4, [x17, #-212]!
 328: b841eef5  ldr w21, [x23, #30]!
 32c: 385f9e2d  ldrb  w13, [x17, #-7]!
 330: 785cec19  ldrh  w25, [x0, #-50]!
 334: 389ebea1  ldrsb x1, [x21, #-21]!
 338: 789caebc  ldrsh x28, [x21, #-54]!
 33c: 78c02c8b  ldrsh w11, [x4, #2]!
 340: b883dd31  ldrsw x17, [x9, #61]!
 344: fc427e7d  ldr d29, [x19, #39]!
 348: bc5abed6  ldr s22, [x22, #-85]!
 34c: fc11ff29  str d9, [x25, #-225]!
 350: bc1f1c49  str s9, [x2, #-15]!
 354: f81be6ed  str x13, [x23], #-66
 358: b800a611  str w17, [x16], #10
 35c: 381e05c1  strb  w1, [x14], #-32
 360: 78006411  strh  w17, [x0], #6
 364: f855473b  ldr x27, [x25], #-172
 368: b85da72d  ldr w13, [x25], #-38
 36c: 385e372b  ldrb  w11, [x25], #-29
 370: 784144be  ldrh  w30, [x5], #20
 374: 389f94e9  ldrsb x9, [x7], #-7
 378: 789c2460  ldrsh x0, [x3], #-62
 37c: 78c1f5c7  ldrsh w7, [x14], #31
 380: b8827771  ldrsw x17, [x27], #39
 384: fc515491  ldr d17, [x4], #-235
 388: bc4226ba  ldr s26, [x21], #34
 38c: fc1c7625  str d5, [x17], #-57
 390: bc1935ad  str s13, [x13], #-109
 394: f824da06  str x6, [x16, w4, sxtw #3]
 398: b834db09  str w9, [x24, w20, sxtw #2]
 39c: 38237ba3  strb  w3, [x29, x3, lsl #0]
 3a0: 783e6a2a  strh  w10, [x17, x30]
 3a4: f867497b  ldr x27, [x11, w7, uxtw]
 3a8: b87949ee  ldr w14, [x15, w25, uxtw]
 3ac: 387379d8  ldrb  w24, [x14, x19, lsl #0]
 3b0: 7866c810  ldrh  w16, [x0, w6, sxtw]
 3b4: 38acd98a  ldrsb x10, [x12, w12, sxtw #0]
 3b8: 78b0499a  ldrsh x26, [x12, w16, uxtw]
 3bc: 78ee781a  ldrsh w26, [x0, x14, lsl #1]
 3c0: b8bbf971  ldrsw x17, [x11, x27, sxtx #2]
 3c4: fc73d803  ldr d3, [x0, w19, sxtw #3]
 3c8: bc6979fa  ldr s26, [x15, x9, lsl #2]
 3cc: fc30e9ab  str d11, [x13, x16, sxtx]
 3d0: bc355a7a  str s26, [x19, w21, uxtw #2]
 3d4: f91886a8  str x8, [x21, #12552]
 3d8: b918ef6a  str w10, [x27, #6380]
 3dc: 391b15db  strb  w27, [x14, #1733]
 3e0: 791ac0f0  strh  w16, [x7, #3424]
 3e4: f958753b  ldr x27, [x9, #12520]
 3e8: b95a1958  ldr w24, [x10, #6680]
 3ec: 395b3f18  ldrb  w24, [x24, #1743]
 3f0: 795800b4  ldrh  w20, [x5, #3072]
 3f4: 39988891  ldrsb x17, [x4, #1570]
 3f8: 799a81ae  ldrsh x14, [x13, #3392]
 3fc: 79dd172a  ldrsh w10, [x25, #3722]
 400: b9981342  ldrsw x2, [x26, #6160]
 404: fd5d21da  ldr d26, [x14, #14912]
 408: bd5e7c9c  ldr s28, [x4, #7804]
 40c: fd1b526e  str d14, [x19, #13984]
 410: bd18df97  str s23, [x28, #6364]
 414: 58002268  ldr x8, 860 <forth>
 418: 18ffdf51  ldr w17, 0 <back>
 41c: f8951080  prfum pldl1keep, [x4, #-175]
 420: d8000000  prfm  pldl1keep, 420 <back+0x420>
 424: f8a4c900  prfm  pldl1keep, [x8, w4, sxtw]
 428: f999e180  prfm  pldl1keep, [x12, #13248]
 42c: 1a150374  adc w20, w27, w21
 430: 3a060227  adcs  w7, w17, w6
 434: 5a1900c5  sbc w5, w6, w25
 438: 7a0e017e  sbcs  w30, w11, w14
 43c: 9a0b0223  adc x3, x17, x11
 440: ba110159  adcs  x25, x10, x17
 444: da170207  sbc x7, x16, x23
 448: fa050144  sbcs  x4, x10, x5
 44c: 0b2973c9  add w9, w30, w9, uxtx #4
 450: 2b30a8a0  adds  w0, w5, w16, sxth #2
 454: cb3b8baf  sub x15, x29, w27, sxtb #2
 458: 6b21f12b  subs  w11, w9, w1, sxtx #4
 45c: 8b264f02  add x2, x24, w6, uxtw #3
 460: ab3a70d3  adds  x19, x6, x26, uxtx #4
 464: cb39ef48  sub x8, x26, x25, sxtx #3
 468: eb29329a  subs  x26, x20, w9, uxth #4
 46c: 3a5a41a7  ccmn  w13, w26, #0x7, mi  // mi = first
 470: 7a54310f  ccmp  w8, w20, #0xf, cc  // cc = lo, ul, last
 474: ba4302c8  ccmn  x22, x3, #0x8, eq  // eq = none
 478: fa58a04a  ccmp  x2, x24, #0xa, ge  // ge = tcont
 47c: 3a50490d  ccmn  w8, #0x10, #0xd, mi  // mi = first
 480: 7a4c0a01  ccmp  w16, #0xc, #0x1, eq  // eq = none
 484: ba5f79e3  ccmn  x15, #0x1f, #0x3, vc
 488: fa4c0aef  ccmp  x23, #0xc, #0xf, eq  // eq = none
 48c: 1a9a30ee  csel  w14, w7, w26, cc  // cc = lo, ul, last
 490: 1a9ed763  csinc w3, w27, w30, le
 494: 5a9702ab  csinv w11, w21, w23, eq  // eq = none
 498: 5a95c7da  csneg w26, w30, w21, gt
 49c: 9a8d835c  csel  x28, x26, x13, hi  // hi = pmore
 4a0: 9a909471  csinc x17, x3, x16, ls  // ls = plast
 4a4: da8380ab  csinv x11, x5, x3, hi  // hi = pmore
 4a8: da93c461  csneg x1, x3, x19, gt
 4ac: 5ac00120  rbit  w0, w9
 4b0: 5ac005da  rev16 w26, w14
 4b4: 5ac00a2d  rev w13, w17
 4b8: 5ac0128b  clz w11, w20
 4bc: 5ac0163c  cls w28, w17
 4c0: dac0008d  rbit  x13, x4
 4c4: dac007c1  rev16 x1, x30
 4c8: dac009cd  rev32 x13, x14
 4cc: dac00d05  rev x5, x8
 4d0: dac01322  clz x2, x25
 4d4: dac01514  cls x20, x8
 4d8: 1adb0b35  udiv  w21, w25, w27
 4dc: 1ad00d4d  sdiv  w13, w10, w16
 4e0: 1ad1203c  lsl w28, w1, w17
 4e4: 1aca26f9  lsr w25, w23, w10
 4e8: 1ac72867  asr w7, w3, w7
 4ec: 1ace2fce  ror w14, w30, w14
 4f0: 9acf0acc  udiv  x12, x22, x15
 4f4: 9acd0f22  sdiv  x2, x25, x13
 4f8: 9ad522e7  lsl x7, x23, x21
 4fc: 9ac0258b  lsr x11, x12, x0
 500: 9adc293e  asr x30, x9, x28
 504: 9ad62cad  ror x13, x5, x22
 508: 9bc47ea5  umulh x5, x21, x4
 50c: 9b477c51  smulh x17, x2, x7
 510: 1b11318c  madd  w12, w12, w17, w12
 514: 1b01edfe  msub  w30, w15, w1, w27
 518: 9b117662  madd  x2, x19, x17, x29
 51c: 9b03fae4  msub  x4, x23, x3, x30
 520: 9b313eef  smaddl  x15, w23, w17, x15
 524: 9b21b59b  smsubl  x27, w12, w1, x13
 528: 9bac45a6  umaddl  x6, w13, w12, x17
 52c: 9ba6a839  umsubl  x25, w1, w6, x10
 530: 1e240871  fmul  s17, s3, s4
 534: 1e3518b0  fdiv  s16, s5, s21
 538: 1e312b63  fadd  s3, s27, s17
 53c: 1e2f3959  fsub  s25, s10, s15
 540: 1e200a2a  fmul  s10, s17, s0
 544: 1e630b5c  fmul  d28, d26, d3
 548: 1e7b1804  fdiv  d4, d0, d27
 54c: 1e6229dc  fadd  d28, d14, d2
 550: 1e773b4c  fsub  d12, d26, d23
 554: 1e610bcf  fmul  d15, d30, d1
 558: 1f0534a4  fmadd s4, s5, s5, s13
 55c: 1f1c85b5  fmsub s21, s13, s28, s1
 560: 1f3d1c71  fnmadd  s17, s3, s29, s7
 564: 1f3d6b37  fnmadd  s23, s25, s29, s26
 568: 1f5e68ee  fmadd d14, d7, d30, d26
 56c: 1f4aa4f6  fmsub d22, d7, d10, d9
 570: 1f6e24e7  fnmadd  d7, d7, d14, d9
 574: 1f6f630e  fnmadd  d14, d24, d15, d24
 578: 1e204056  fmov  s22, s2
 57c: 1e20c060  fabs  s0, s3
 580: 1e214229  fneg  s9, s17
 584: 1e21c178  fsqrt s24, s11
 588: 1e22c32f  fcvt  d15, s25
 58c: 1e604064  fmov  d4, d3
 590: 1e60c2da  fabs  d26, d22
 594: 1e61427e  fneg  d30, d19
 598: 1e61c1cc  fsqrt d12, d14
 59c: 1e6240f1  fcvt  s17, d7
 5a0: 1e3801d8  fcvtzs  w24, s14
 5a4: 9e38034d  fcvtzs  x13, s26
 5a8: 1e780022  fcvtzs  w2, d1
 5ac: 9e780165  fcvtzs  x5, d11
 5b0: 1e22026e  scvtf s14, w19
 5b4: 9e2202c1  scvtf s1, x22
 5b8: 1e62023b  scvtf d27, w17
 5bc: 9e620136  scvtf d22, x9
 5c0: 1e26006e  fmov  w14, s3
 5c4: 9e66022c  fmov  x12, d17
 5c8: 1e270368  fmov  s8, w27
 5cc: 9e67039d  fmov  d29, x28
 5d0: 1e3e2000  fcmp  s0, s30
 5d4: 1e692180  fcmp  d12, d9
 5d8: 1e202148  fcmp  s10, #0.0
 5dc: 1e602328  fcmp  d25, #0.0
 5e0: 292e7b68  stp w8, w30, [x27, #-144]
 5e4: 294a4f15  ldp w21, w19, [x24, #80]
 5e8: 69626c50  ldpsw x16, x27, [x2, #-240]
 5ec: a93814d5  stp x21, x5, [x6, #-128]
 5f0: a97e679d  ldp x29, x25, [x28, #-32]
 5f4: 29903408  stp w8, w13, [x0, #128]!
 5f8: 29ec5039  ldp w25, w20, [x1, #-160]!
 5fc: 69fc62ce  ldpsw x14, x24, [x22, #-32]!
 600: a98504d1  stp x17, x1, [x6, #80]!
 604: a9fc4735  ldp x21, x17, [x25, #-64]!
 608: 28b05691  stp w17, w21, [x20], #-128
 60c: 28c8705c  ldp w28, w28, [x2], #64
 610: 68e07953  ldpsw x19, x30, [x10], #-256
 614: a8bf3e31  stp x17, x15, [x17], #-16
 618: a8fe0331  ldp x17, x0, [x25], #-32
 61c: 283c170e  stnp  w14, w5, [x24, #-32]
 620: 284e4c37  ldnp  w23, w19, [x1, #112]
 624: a80419cb  stnp  x11, x6, [x14, #64]
 628: a8722f62  ldnp  x2, x11, [x27, #-224]
 62c: 0c407230  ld1 {v16.8b}, [x17]
 630: 4cdfa13d  ld1 {v29.16b, v30.16b}, [x9], #32
 634: 0cd56f1e  ld1 {v30.1d, v31.1d, v0.1d}, [x24], x21
 638: 4cdf2440  ld1 {v0.8h-v3.8h}, [x2], #64
 63c: 0d40c134  ld1r  {v20.8b}, [x9]
 640: 4ddfc811  ld1r  {v17.4s}, [x0], #4
 644: 0ddaced5  ld1r  {v21.1d}, [x22], x26
 648: 4c408f33  ld2 {v19.2d, v20.2d}, [x25]
 64c: 0cdf84aa  ld2 {v10.4h, v11.4h}, [x5], #16
 650: 4d60c30a  ld2r  {v10.16b, v11.16b}, [x24]
 654: 0dffcbad  ld2r  {v13.2s, v14.2s}, [x29], #8
 658: 4de2cf96  ld2r  {v22.2d, v23.2d}, [x28], x2
 65c: 4ccb489e  ld3 {v30.4s, v31.4s, v0.4s}, [x4], x11
 660: 0c40481d  ld3 {v29.2s-v31.2s}, [x0]
 664: 4d40e777  ld3r  {v23.8h-v25.8h}, [x27]
 668: 4ddfe943  ld3r  {v3.4s-v5.4s}, [x10], #12
 66c: 0dd6edd3  ld3r  {v19.1d-v21.1d}, [x14], x22
 670: 4cdf040e  ld4 {v14.8h-v17.8h}, [x0], #64
 674: 0cd902de  ld4 {v30.8b, v31.8b, v0.8b, v1.8b}, [x22], x25
 678: 0d60e019  ld4r  {v25.8b-v28.8b}, [x0]
 67c: 0dffe50a  ld4r  {v10.4h-v13.4h}, [x8], #8
 680: 0dfce8c1  ld4r  {v1.2s-v4.2s}, [x6], x28
 684: ba5fd3e3  ccmn  xzr, xzr, #0x3, le
 688: 3a5f03e5  ccmn  wzr, wzr, #0x5, eq  // eq = none
 68c: fa411be4  ccmp  xzr, #0x1, #0x4, ne  // ne = any
 690: 7a42cbe2  ccmp  wzr, #0x2, #0x2, gt
 694: 93df03ff  ror xzr, xzr, #0
 698: c820ffff  stlxp w0, xzr, xzr, [sp]
 69c: 8822fc7f  stlxp w2, wzr, wzr, [x3]
 6a0: c8247cbf  stxp  w4, xzr, xzr, [x5]
 6a4: 88267fff  stxp  w6, wzr, wzr, [sp]
 6a8: 4e010fe0  dup v0.16b, wzr
 6ac: 4e081fe1  mov v1.d[0], xzr
 6b0: 4e0c1fe1  mov v1.s[1], wzr
 6b4: 4e0a1fe1  mov v1.h[2], wzr
 6b8: 4e071fe1  mov v1.b[3], wzr
 6bc: 4cc0ac3f  ld1 {v31.2d, v0.2d}, [x1], x0
 6c0: 1e601000  fmov  d0, #2.000000000000000000e+00
 6c4: 1e603000  fmov  d0, #2.125000000000000000e+00
 6c8: 1e621000  fmov  d0, #4.000000000000000000e+00
 6cc: 1e623000  fmov  d0, #4.250000000000000000e+00
 6d0: 1e641000  fmov  d0, #8.000000000000000000e+00
 6d4: 1e643000  fmov  d0, #8.500000000000000000e+00
 6d8: 1e661000  fmov  d0, #1.600000000000000000e+01
 6dc: 1e663000  fmov  d0, #1.700000000000000000e+01
 6e0: 1e681000  fmov  d0, #1.250000000000000000e-01
 6e4: 1e683000  fmov  d0, #1.328125000000000000e-01
 6e8: 1e6a1000  fmov  d0, #2.500000000000000000e-01
 6ec: 1e6a3000  fmov  d0, #2.656250000000000000e-01
 6f0: 1e6c1000  fmov  d0, #5.000000000000000000e-01
 6f4: 1e6c3000  fmov  d0, #5.312500000000000000e-01
 6f8: 1e6e1000  fmov  d0, #1.000000000000000000e+00
 6fc: 1e6e3000  fmov  d0, #1.062500000000000000e+00
 700: 1e701000  fmov  d0, #-2.000000000000000000e+00
 704: 1e703000  fmov  d0, #-2.125000000000000000e+00
 708: 1e721000  fmov  d0, #-4.000000000000000000e+00
 70c: 1e723000  fmov  d0, #-4.250000000000000000e+00
 710: 1e741000  fmov  d0, #-8.000000000000000000e+00
 714: 1e743000  fmov  d0, #-8.500000000000000000e+00
 718: 1e761000  fmov  d0, #-1.600000000000000000e+01
 71c: 1e763000  fmov  d0, #-1.700000000000000000e+01
 720: 1e781000  fmov  d0, #-1.250000000000000000e-01
 724: 1e783000  fmov  d0, #-1.328125000000000000e-01
 728: 1e7a1000  fmov  d0, #-2.500000000000000000e-01
 72c: 1e7a3000  fmov  d0, #-2.656250000000000000e-01
 730: 1e7c1000  fmov  d0, #-5.000000000000000000e-01
 734: 1e7c3000  fmov  d0, #-5.312500000000000000e-01
 738: 1e7e1000  fmov  d0, #-1.000000000000000000e+00
 73c: 1e7e3000  fmov  d0, #-1.062500000000000000e+00
 740: f83081f4  swp x16, x20, [x15]
 744: f8220387  ldadd x2, x7, [x28]
 748: f834132a  ldclr x20, x10, [x25]
 74c: f836204b  ldeor x22, x11, [x2]
 750: f821326a  ldset x1, x10, [x19]
 754: f82e5075  ldsmin  x14, x21, [x3]
 758: f83c41bb  ldsmax  x28, x27, [x13]
 75c: f83172be  ldumin  x17, x30, [x21]
 760: f83b63b0  ldumax  x27, x16, [x29]
 764: f8be8009  swpa  x30, x9, [x0]
 768: f8bc039b  ldadda  x28, x27, [x28]
 76c: f8b51159  ldclra  x21, x25, [x10]
 770: f8bf21f4  ldeora  xzr, x20, [x15]
 774: f8a131d9  ldseta  x1, x25, [x14]
 778: f8b553ba  ldsmina x21, x26, [x29]
 77c: f8a8433d  ldsmaxa x8, x29, [x25]
 780: f8ad7322  ldumina x13, x2, [x25]
 784: f8af6017  ldumaxa x15, x23, [x0]
 788: f8e38041  swpal x3, x1, [x2]
 78c: f8fc0283  ldaddal x28, x3, [x20]
 790: f8ee11df  ldclral x14, xzr, [x14]
 794: f8e7205c  ldeoral x7, x28, [x2]
 798: f8e030ab  ldsetal x0, x11, [x5]
 79c: f8eb528e  ldsminal  x11, x14, [x20]
 7a0: f8ff4044  ldsmaxal  xzr, x4, [x2]
 7a4: f8fa72c0  lduminal  x26, x0, [x22]
 7a8: f8f161a1  ldumaxal  x17, x1, [x13]
 7ac: f877829a  swpl  x23, x26, [x20]
 7b0: f86e018b  ldaddl  x14, x11, [x12]
 7b4: f86c11ff  stclrl  x12, [x15]
 7b8: f87b210e  ldeorl  x27, x14, [x8]
 7bc: f86a333e  ldsetl  x10, x30, [x25]
 7c0: f8765207  ldsminl x22, x7, [x16]
 7c4: f8614110  ldsmaxl x1, x16, [x8]
 7c8: f8617341  lduminl x1, x1, [x26]
 7cc: f86061f7  ldumaxl x0, x23, [x15]
 7d0: b82b8110  swp w11, w16, [x8]
 7d4: b82101c7  ldadd w1, w7, [x14]
 7d8: b830113f  stclr w16, [x9]
 7dc: b83621a6  ldeor w22, w6, [x13]
 7e0: b82b308d  ldset w11, w13, [x4]
 7e4: b8305016  ldsmin  w16, w22, [x0]
 7e8: b83c415f  stsmax  w28, [x10]
 7ec: b8307105  ldumin  w16, w5, [x8]
 7f0: b83a61f4  ldumax  w26, w20, [x15]
 7f4: b8bb8206  swpa  w27, w6, [x16]
 7f8: b8bf005f  ldadda  wzr, wzr, [x2]
 7fc: b8b8111c  ldclra  w24, w28, [x8]
 800: b8af22e9  ldeora  w15, w9, [x23]
 804: b8ba30e2  ldseta  w26, w2, [x7]
 808: b8a351f1  ldsmina w3, w17, [x15]
 80c: b8b342a5  ldsmaxa w19, w5, [x21]
 810: b8a7719a  ldumina w7, w26, [x12]
 814: b8ac63a7  ldumaxa w12, w7, [x29]
 818: b8e98288  swpal w9, w8, [x20]
 81c: b8e803df  ldaddal w8, wzr, [x30]
 820: b8e01186  ldclral w0, w6, [x12]
 824: b8f12057  ldeoral w17, w23, [x2]
 828: b8e0303e  ldsetal w0, w30, [x1]
 82c: b8f651e3  ldsminal  w22, w3, [x15]
 830: b8f941b5  ldsmaxal  w25, w21, [x13]
 834: b8ed7378  lduminal  w13, w24, [x27]
 838: b8f46163  ldumaxal  w20, w3, [x11]
 83c: b86382ad  swpl  w3, w13, [x21]
 840: b87a034f  ldaddl  w26, w15, [x26]
 844: b8691053  ldclrl  w9, w19, [x2]
 848: b87820fd  ldeorl  w24, w29, [x7]
 84c: b87d31f9  ldsetl  w29, w25, [x15]
 850: b86b50fe  ldsminl w11, w30, [x7]
 854: b86b40c2  ldsmaxl w11, w2, [x6]
 858: b87071cb  lduminl w16, w11, [x14]
 85c: b8656168  ldumaxl w5, w8, [x11]
 */

  static const unsigned int insns[] =
  {
    0x8b18ec0f,     0xcb9636d1,     0xab1ce74a,     0xeb184a19,
    0x0b1c1ca8,     0x4b817388,     0x2b01004c,     0x6b5164b7,
    0x8a0d5595,     0xaa9791f5,     0xca9bc316,     0xea82d1f6,
    0x0a980e21,     0x2a862c45,     0x4a453037,     0x6a8e5180,
    0x8a621cc1,     0xaa24bd1e,     0xcab4d6d1,     0xeaa591fd,
    0x0a7d6efe,     0x2a2253ac,     0x4aa61187,     0x6aa755b0,
    0x110b5a25,     0x31056e0a,     0x510f48ba,     0x710ac715,
    0x910f6e0a,     0xb10a65ef,     0xd1009e98,     0xf10131aa,
    0x121d4e67,     0x32043e25,     0x52132390,     0x72160b0e,
    0x9273e76e,     0xb256416c,     0xd24b5002,     0xf266da8d,
    0x14000000,     0x17ffffd7,     0x140001ee,     0x94000000,
    0x97ffffd4,     0x940001eb,     0x3400000f,     0x34fffa2f,
    0x34003d0f,     0x3500001c,     0x35fff9dc,     0x35003cbc,
    0xb400001b,     0xb4fff97b,     0xb4003c5b,     0xb5000000,
    0xb5fff900,     0xb5003be0,     0x1000000d,     0x10fff8ad,
    0x10003b8d,     0x90000003,     0x36380015,     0x363ff835,
    0x36383b15,     0x3748000f,     0x374ff7cf,     0x37483aaf,
    0x12a14bee,     0x5283bb51,     0x72858ebb,     0x92c98881,
    0xd2aa50d4,     0xf2afd9d4,     0x935c504d,     0x33133e90,
    0x5309196b,     0x93595482,     0xb3424e0d,     0xd3481728,
    0x138a3b7d,     0x93c66286,     0x54000000,     0x54fff5a0,
    0x54003880,     0x54000001,     0x54fff541,     0x54003821,
    0x54000002,     0x54fff4e2,     0x540037c2,     0x54000002,
    0x54fff482,     0x54003762,     0x54000003,     0x54fff423,
    0x54003703,     0x54000003,     0x54fff3c3,     0x540036a3,
    0x54000004,     0x54fff364,     0x54003644,     0x54000005,
    0x54fff305,     0x540035e5,     0x54000006,     0x54fff2a6,
    0x54003586,     0x54000007,     0x54fff247,     0x54003527,
    0x54000008,     0x54fff1e8,     0x540034c8,     0x54000009,
    0x54fff189,     0x54003469,     0x5400000a,     0x54fff12a,
    0x5400340a,     0x5400000b,     0x54fff0cb,     0x540033ab,
    0x5400000c,     0x54fff06c,     0x5400334c,     0x5400000d,
    0x54fff00d,     0x540032ed,     0x5400000e,     0x54ffefae,
    0x5400328e,     0x5400000f,     0x54ffef4f,     0x5400322f,
    0xd40d2881,     0xd40ea5c2,     0xd40518a3,     0xd42eca40,
    0xd44a2e60,     0xd503201f,     0xd69f03e0,     0xd6bf03e0,
    0xd5033fdf,     0xd5033d9f,     0xd5033bbf,     0xd61f0120,
    0xd63f0120,     0xc8027d7d,     0xc816ff85,     0xc85f7e8e,
    0xc85ffe7d,     0xc89ffea6,     0xc8dffc73,     0x880c7f63,
    0x8811fdfa,     0x885f7dcd,     0x885fff4c,     0x889ffe28,
    0x88dfffd5,     0x48007d6f,     0x4811fc34,     0x485f7d1d,
    0x485ffd91,     0x489ffc8b,     0x48dffc90,     0x080e7c85,
    0x081bfe11,     0x085f7f66,     0x085fff1b,     0x089ffe8a,
    0x08dfff49,     0xc87f7b85,     0xc87fa66a,     0xc82b5590,
    0xc82adc94,     0x887f0416,     0x887f8503,     0x88205fc9,
    0x8837c560,     0xf81e1146,     0xb81fb007,     0x381f3205,
    0x7801f27e,     0xf8477130,     0xb843b208,     0x385f918a,
    0x785da12e,     0x389f83d8,     0x78817087,     0x78dd91d1,
    0xb89e136b,     0xfc4410ec,     0xbc5fe200,     0xfc15f2ed,
    0xbc1c2075,     0xf8064ca2,     0xb81a4c29,     0x381fbfdb,
    0x7800cdfb,     0xf852ce24,     0xb841eef5,     0x385f9e2d,
    0x785cec19,     0x389ebea1,     0x789caebc,     0x78c02c8b,
    0xb883dd31,     0xfc427e7d,     0xbc5abed6,     0xfc11ff29,
    0xbc1f1c49,     0xf81be6ed,     0xb800a611,     0x381e05c1,
    0x78006411,     0xf855473b,     0xb85da72d,     0x385e372b,
    0x784144be,     0x389f94e9,     0x789c2460,     0x78c1f5c7,
    0xb8827771,     0xfc515491,     0xbc4226ba,     0xfc1c7625,
    0xbc1935ad,     0xf824da06,     0xb834db09,     0x38237ba3,
    0x783e6a2a,     0xf867497b,     0xb87949ee,     0x387379d8,
    0x7866c810,     0x38acd98a,     0x78b0499a,     0x78ee781a,
    0xb8bbf971,     0xfc73d803,     0xbc6979fa,     0xfc30e9ab,
    0xbc355a7a,     0xf91886a8,     0xb918ef6a,     0x391b15db,
    0x791ac0f0,     0xf958753b,     0xb95a1958,     0x395b3f18,
    0x795800b4,     0x39988891,     0x799a81ae,     0x79dd172a,
    0xb9981342,     0xfd5d21da,     0xbd5e7c9c,     0xfd1b526e,
    0xbd18df97,     0x58002268,     0x18ffdf51,     0xf8951080,
    0xd8000000,     0xf8a4c900,     0xf999e180,     0x1a150374,
    0x3a060227,     0x5a1900c5,     0x7a0e017e,     0x9a0b0223,
    0xba110159,     0xda170207,     0xfa050144,     0x0b2973c9,
    0x2b30a8a0,     0xcb3b8baf,     0x6b21f12b,     0x8b264f02,
    0xab3a70d3,     0xcb39ef48,     0xeb29329a,     0x3a5a41a7,
    0x7a54310f,     0xba4302c8,     0xfa58a04a,     0x3a50490d,
    0x7a4c0a01,     0xba5f79e3,     0xfa4c0aef,     0x1a9a30ee,
    0x1a9ed763,     0x5a9702ab,     0x5a95c7da,     0x9a8d835c,
    0x9a909471,     0xda8380ab,     0xda93c461,     0x5ac00120,
    0x5ac005da,     0x5ac00a2d,     0x5ac0128b,     0x5ac0163c,
    0xdac0008d,     0xdac007c1,     0xdac009cd,     0xdac00d05,
    0xdac01322,     0xdac01514,     0x1adb0b35,     0x1ad00d4d,
    0x1ad1203c,     0x1aca26f9,     0x1ac72867,     0x1ace2fce,
    0x9acf0acc,     0x9acd0f22,     0x9ad522e7,     0x9ac0258b,
    0x9adc293e,     0x9ad62cad,     0x9bc47ea5,     0x9b477c51,
    0x1b11318c,     0x1b01edfe,     0x9b117662,     0x9b03fae4,
    0x9b313eef,     0x9b21b59b,     0x9bac45a6,     0x9ba6a839,
    0x1e240871,     0x1e3518b0,     0x1e312b63,     0x1e2f3959,
    0x1e200a2a,     0x1e630b5c,     0x1e7b1804,     0x1e6229dc,
    0x1e773b4c,     0x1e610bcf,     0x1f0534a4,     0x1f1c85b5,
    0x1f3d1c71,     0x1f3d6b37,     0x1f5e68ee,     0x1f4aa4f6,
    0x1f6e24e7,     0x1f6f630e,     0x1e204056,     0x1e20c060,
    0x1e214229,     0x1e21c178,     0x1e22c32f,     0x1e604064,
    0x1e60c2da,     0x1e61427e,     0x1e61c1cc,     0x1e6240f1,
    0x1e3801d8,     0x9e38034d,     0x1e780022,     0x9e780165,
    0x1e22026e,     0x9e2202c1,     0x1e62023b,     0x9e620136,
    0x1e26006e,     0x9e66022c,     0x1e270368,     0x9e67039d,
    0x1e3e2000,     0x1e692180,     0x1e202148,     0x1e602328,
    0x292e7b68,     0x294a4f15,     0x69626c50,     0xa93814d5,
    0xa97e679d,     0x29903408,     0x29ec5039,     0x69fc62ce,
    0xa98504d1,     0xa9fc4735,     0x28b05691,     0x28c8705c,
    0x68e07953,     0xa8bf3e31,     0xa8fe0331,     0x283c170e,
    0x284e4c37,     0xa80419cb,     0xa8722f62,     0x0c407230,
    0x4cdfa13d,     0x0cd56f1e,     0x4cdf2440,     0x0d40c134,
    0x4ddfc811,     0x0ddaced5,     0x4c408f33,     0x0cdf84aa,
    0x4d60c30a,     0x0dffcbad,     0x4de2cf96,     0x4ccb489e,
    0x0c40481d,     0x4d40e777,     0x4ddfe943,     0x0dd6edd3,
    0x4cdf040e,     0x0cd902de,     0x0d60e019,     0x0dffe50a,
    0x0dfce8c1,     0xba5fd3e3,     0x3a5f03e5,     0xfa411be4,
    0x7a42cbe2,     0x93df03ff,     0xc820ffff,     0x8822fc7f,
    0xc8247cbf,     0x88267fff,     0x4e010fe0,     0x4e081fe1,
    0x4e0c1fe1,     0x4e0a1fe1,     0x4e071fe1,     0x4cc0ac3f,
    0x1e601000,     0x1e603000,     0x1e621000,     0x1e623000,
    0x1e641000,     0x1e643000,     0x1e661000,     0x1e663000,
    0x1e681000,     0x1e683000,     0x1e6a1000,     0x1e6a3000,
    0x1e6c1000,     0x1e6c3000,     0x1e6e1000,     0x1e6e3000,
    0x1e701000,     0x1e703000,     0x1e721000,     0x1e723000,
    0x1e741000,     0x1e743000,     0x1e761000,     0x1e763000,
    0x1e781000,     0x1e783000,     0x1e7a1000,     0x1e7a3000,
    0x1e7c1000,     0x1e7c3000,     0x1e7e1000,     0x1e7e3000,
    0xf83081f4,     0xf8220387,     0xf834132a,     0xf836204b,
    0xf821326a,     0xf82e5075,     0xf83c41bb,     0xf83172be,
    0xf83b63b0,     0xf8be8009,     0xf8bc039b,     0xf8b51159,
    0xf8bf21f4,     0xf8a131d9,     0xf8b553ba,     0xf8a8433d,
    0xf8ad7322,     0xf8af6017,     0xf8e38041,     0xf8fc0283,
    0xf8ee11df,     0xf8e7205c,     0xf8e030ab,     0xf8eb528e,
    0xf8ff4044,     0xf8fa72c0,     0xf8f161a1,     0xf877829a,
    0xf86e018b,     0xf86c11ff,     0xf87b210e,     0xf86a333e,
    0xf8765207,     0xf8614110,     0xf8617341,     0xf86061f7,
    0xb82b8110,     0xb82101c7,     0xb830113f,     0xb83621a6,
    0xb82b308d,     0xb8305016,     0xb83c415f,     0xb8307105,
    0xb83a61f4,     0xb8bb8206,     0xb8bf005f,     0xb8b8111c,
    0xb8af22e9,     0xb8ba30e2,     0xb8a351f1,     0xb8b342a5,
    0xb8a7719a,     0xb8ac63a7,     0xb8e98288,     0xb8e803df,
    0xb8e01186,     0xb8f12057,     0xb8e0303e,     0xb8f651e3,
    0xb8f941b5,     0xb8ed7378,     0xb8f46163,     0xb86382ad,
    0xb87a034f,     0xb8691053,     0xb87820fd,     0xb87d31f9,
    0xb86b50fe,     0xb86b40c2,     0xb87071cb,     0xb8656168,

  };
// END  Generated code -- do not edit

  asm_check((unsigned int *)entry, insns, sizeof insns / sizeof insns[0]);

  {
    address PC = __ pc();
    __ ld1(v0, __ T16B, Address(r16));      // No offset
    __ ld1(v0, __ T8H, __ post(r16, 16));   // Post-index
    __ ld2(v0, v1, __ T8H, __ post(r24, 16 * 2));   // Post-index
    __ ld1(v0, __ T16B, __ post(r16, r17)); // Register post-index
    static const unsigned int vector_insns[] = {
       0x4c407200, // ld1   {v0.16b}, [x16]
       0x4cdf7600, // ld1   {v0.8h}, [x16], #16
       0x4cdf8700, // ld2   {v0.8h, v1.8h}, [x24], #32
       0x4cd17200, // ld1   {v0.16b}, [x16], x17
      };
    asm_check((unsigned int *)PC, vector_insns,
              sizeof vector_insns / sizeof vector_insns[0]);
  }
}
#endif // ASSERT

#undef __

void Assembler::emit_data64(jlong data,
                            relocInfo::relocType rtype,
                            int format) {
  if (rtype == relocInfo::none) {
    emit_int64(data);
  } else {
    emit_data64(data, Relocation::spec_simple(rtype), format);
  }
}

void Assembler::emit_data64(jlong data,
                            RelocationHolder const& rspec,
                            int format) {

  assert(inst_mark() != NULL, "must be inside InstructionMark");
  // Do not use AbstractAssembler::relocate, which is not intended for
  // embedded words.  Instead, relocate to the enclosing instruction.
  code_section()->relocate(inst_mark(), rspec, format);
  emit_int64(data);
}

extern "C" {
  void das(uint64_t start, int len) {
    ResourceMark rm;
    len <<= 2;
    if (len < 0)
      Disassembler::decode((address)start + len, (address)start);
    else
      Disassembler::decode((address)start, (address)start + len);
  }

  JNIEXPORT void das1(uintptr_t insn) {
    das(insn, 1);
  }
}

#define gas_assert(ARG1) assert(ARG1, #ARG1)

#define __ as->

void Address::lea(MacroAssembler *as, Register r) const {
  Relocation* reloc = _rspec.reloc();
  relocInfo::relocType rtype = (relocInfo::relocType) reloc->type();

  switch(_mode) {
  case base_plus_offset: {
    if (_offset == 0 && _base == r) // it's a nop
      break;
    if (_offset > 0)
      __ add(r, _base, _offset);
    else
      __ sub(r, _base, -_offset);
      break;
  }
  case base_plus_offset_reg: {
    __ add(r, _base, _index, _ext.op(), MAX2(_ext.shift(), 0));
    break;
  }
  case literal: {
    if (rtype == relocInfo::none)
      __ mov(r, target());
    else
      __ movptr(r, (uint64_t)target());
    break;
  }
  default:
    ShouldNotReachHere();
  }
}

void Assembler::adrp(Register reg1, const Address &dest, uint64_t &byte_offset) {
  ShouldNotReachHere();
}

#undef __

#define starti Instruction_aarch64 do_not_use(this); set_current(&do_not_use)

  void Assembler::adr(Register Rd, address adr) {
    intptr_t offset = adr - pc();
    int offset_lo = offset & 3;
    offset >>= 2;
    starti;
    f(0, 31), f(offset_lo, 30, 29), f(0b10000, 28, 24), sf(offset, 23, 5);
    rf(Rd, 0);
  }

  void Assembler::_adrp(Register Rd, address adr) {
    uint64_t pc_page = (uint64_t)pc() >> 12;
    uint64_t adr_page = (uint64_t)adr >> 12;
    intptr_t offset = adr_page - pc_page;
    int offset_lo = offset & 3;
    offset >>= 2;
    starti;
    f(1, 31), f(offset_lo, 30, 29), f(0b10000, 28, 24), sf(offset, 23, 5);
    rf(Rd, 0);
  }

#undef starti

Address::Address(address target, relocInfo::relocType rtype) : _mode(literal){
  _is_lval = false;
  _target = target;
  switch (rtype) {
  case relocInfo::oop_type:
  case relocInfo::metadata_type:
    // Oops are a special case. Normally they would be their own section
    // but in cases like icBuffer they are literals in the code stream that
    // we don't have a section for. We use none so that we get a literal address
    // which is always patchable.
    break;
  case relocInfo::external_word_type:
    _rspec = external_word_Relocation::spec(target);
    break;
  case relocInfo::internal_word_type:
    _rspec = internal_word_Relocation::spec(target);
    break;
  case relocInfo::opt_virtual_call_type:
    _rspec = opt_virtual_call_Relocation::spec();
    break;
  case relocInfo::static_call_type:
    _rspec = static_call_Relocation::spec();
    break;
  case relocInfo::runtime_call_type:
    _rspec = runtime_call_Relocation::spec();
    break;
  case relocInfo::poll_type:
  case relocInfo::poll_return_type:
    _rspec = Relocation::spec_simple(rtype);
    break;
  case relocInfo::none:
    _rspec = RelocationHolder::none;
    break;
  default:
    ShouldNotReachHere();
    break;
  }
}

void Assembler::b(const Address &dest) {
  code_section()->relocate(pc(), dest.rspec());
  b(dest.target());
}

void Assembler::bl(const Address &dest) {
  code_section()->relocate(pc(), dest.rspec());
  bl(dest.target());
}

void Assembler::adr(Register r, const Address &dest) {
  code_section()->relocate(pc(), dest.rspec());
  adr(r, dest.target());
}

void Assembler::br(Condition cc, Label &L) {
  if (L.is_bound()) {
    br(cc, target(L));
  } else {
    L.add_patch_at(code(), locator());
    br(cc, pc());
  }
}

void Assembler::wrap_label(Label &L,
                                 Assembler::uncond_branch_insn insn) {
  if (L.is_bound()) {
    (this->*insn)(target(L));
  } else {
    L.add_patch_at(code(), locator());
    (this->*insn)(pc());
  }
}

void Assembler::wrap_label(Register r, Label &L,
                                 compare_and_branch_insn insn) {
  if (L.is_bound()) {
    (this->*insn)(r, target(L));
  } else {
    L.add_patch_at(code(), locator());
    (this->*insn)(r, pc());
  }
}

void Assembler::wrap_label(Register r, int bitpos, Label &L,
                                 test_and_branch_insn insn) {
  if (L.is_bound()) {
    (this->*insn)(r, bitpos, target(L));
  } else {
    L.add_patch_at(code(), locator());
    (this->*insn)(r, bitpos, pc());
  }
}

void Assembler::wrap_label(Label &L, prfop op, prefetch_insn insn) {
  if (L.is_bound()) {
    (this->*insn)(target(L), op);
  } else {
    L.add_patch_at(code(), locator());
    (this->*insn)(pc(), op);
  }
}

// An "all-purpose" add/subtract immediate, per ARM documentation:
// A "programmer-friendly" assembler may accept a negative immediate
// between -(2^24 -1) and -1 inclusive, causing it to convert a
// requested ADD operation to a SUB, or vice versa, and then encode
// the absolute value of the immediate as for uimm24.
void Assembler::add_sub_immediate(Register Rd, Register Rn, unsigned uimm, int op,
                                  int negated_op) {
  bool sets_flags = op & 1;   // this op sets flags
  union {
    unsigned u;
    int imm;
  };
  u = uimm;
  bool shift = false;
  bool neg = imm < 0;
  if (neg) {
    imm = -imm;
    op = negated_op;
  }
  assert(Rd != sp || imm % 16 == 0, "misaligned stack");
  if (imm >= (1 << 11)
      && ((imm >> 12) << 12 == imm)) {
    imm >>= 12;
    shift = true;
  }
  f(op, 31, 29), f(0b10001, 28, 24), f(shift, 23, 22), f(imm, 21, 10);

  // add/subtract immediate ops with the S bit set treat r31 as zr;
  // with S unset they use sp.
  if (sets_flags)
    zrf(Rd, 0);
  else
    srf(Rd, 0);

  srf(Rn, 5);
}

bool Assembler::operand_valid_for_add_sub_immediate(int64_t imm) {
  uint64_t uimm = (uint64_t)uabs((jlong)imm);
  if (uimm < (1 << 12))
    return true;
  if (uimm < (1 << 24)
      && ((uimm >> 12) << 12 == uimm)) {
    return true;
  }
  return false;
}

bool Assembler::operand_valid_for_logical_immediate(bool is32, uint64_t imm) {
  return encode_logical_immediate(is32, imm) != 0xffffffff;
}

static uint64_t doubleTo64Bits(jdouble d) {
  union {
    jdouble double_value;
    uint64_t double_bits;
  };

  double_value = d;
  return double_bits;
}

bool Assembler::operand_valid_for_float_immediate(double imm) {
  // If imm is all zero bits we can use ZR as the source of a
  // floating-point value.
  if (doubleTo64Bits(imm) == 0)
    return true;

  // Otherwise try to encode imm then convert the encoded value back
  // and make sure it's the exact same bit pattern.
  unsigned result = encoding_for_fp_immediate(imm);
  return doubleTo64Bits(imm) == fp_immediate_for_encoding(result, true);
}

int AbstractAssembler::code_fill_byte() {
  return 0;
}

// n.b. this is implemented in subclass MacroAssembler
void Assembler::bang_stack_with_offset(int offset) { Unimplemented(); }


// and now the routines called by the assembler which encapsulate the
// above encode and decode functions

uint32_t
asm_util::encode_logical_immediate(bool is32, uint64_t imm)
{
  if (is32) {
    /* Allow all zeros or all ones in top 32-bits, so that
       constant expressions like ~1 are permitted. */
    if (imm >> 32 != 0 && imm >> 32 != 0xffffffff)
      return 0xffffffff;
    /* Replicate the 32 lower bits to the 32 upper bits.  */
    imm &= 0xffffffff;
    imm |= imm << 32;
  }

  return encoding_for_logical_immediate(imm);
}

unsigned Assembler::pack(double value) {
  float val = (float)value;
  unsigned result = encoding_for_fp_immediate(val);
  guarantee(unpack(result) == value,
            "Invalid floating-point immediate operand");
  return result;
}

// Packed operands for  Floating-point Move (immediate)

static float unpack(unsigned value) {
  union {
    unsigned ival;
    float val;
  };
  ival = fp_immediate_for_encoding(value, 0);
  return val;
}

address Assembler::locate_next_instruction(address inst) {
  return inst + Assembler::instruction_size;
}
